Spring中常用的设计模式
非常好!为了帮助你更直观、深入地理解 Spring 中常用的设计模式,下面我将结合 具体的代码示例,逐一说明这些设计模式在 Spring 中是如何体现和应用的,包括 关键类、注解、配置 和 实际使用场景。
一、IoC(控制反转)与 DI(依赖注入)【核心思想,非 GoF 模式】
🎯 模式说明:
将对象的创建权和依赖管理交给 Spring 容器,而不是开发者手动 new。
✅ 代码示例:
@Service
public class UserService {// 由 Spring 自动注入,不用手动 new@Autowiredprivate UserRepository userRepository;public void addUser(String name) {userRepository.save(name);}
}@Repository
public class UserRepository {public void save(String name) {System.out.println("保存用户: " + name);}
}
说明:
UserService
依赖UserRepository
,但不需要手动创建,而是由 Spring 容器自动注入(DI),这就是 控制反转(IoC) 的体现。
二、工厂模式(Factory Pattern)
🎯 模式说明:
对象的创建由专门的工厂管理,而不是直接使用 new
。
✅ 代码示例:Spring 的 BeanFactory / ApplicationContext
Spring 自带的核心容器就是工厂模式的实现:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从工厂(容器)中获取 Bean,而不是手动 new
UserService userService = context.getBean(UserService.class);
userService.addUser("小明");
说明:
ApplicationContext
是 Spring 提供的一个高级“工厂”,负责管理所有 Bean 的创建和依赖注入。
三、单例模式(Singleton Pattern)
🎯 模式说明:
确保一个类只有一个实例,并提供全局访问点。
✅ 代码示例:Spring 默认的 Bean 作用域就是单例
@Service
public class CounterService {private int count = 0;public void increment() {count++;}public int getCount() {return count;}
}
测试代码:
@Autowired
private CounterService counterService1;@Autowired
private CounterService counterService2;System.out.println(counterService1.getCount()); // 0
counterService1.increment();
System.out.println(counterService2.getCount()); // 1,说明是同一个实例
说明: Spring 中默认的 Bean 作用域是 singleton(单例),即整个容器中只存在一个实例,所有注入的地方都共享该对象。
四、代理模式(Proxy Pattern)
🎯 模式说明:
为对象提供一个代理,以控制对这个对象的访问,常用于 AOP。
✅ 代码示例:使用 @Transactional 注解(底层使用代理实现事务)
@Service
public class OrderService {@Transactional // 由 Spring AOP 生成代理,实现事务管理public void createOrder(String orderId) {System.out.println("创建订单:" + orderId);// 模拟异常if (true) throw new RuntimeException("模拟异常,触发回滚");}
}
说明: 当你使用
@Transactional
,Spring 会为OrderService
创建一个 代理对象,在方法执行前后加入事务控制逻辑,而你无需手动编写事务代码。
🔍 底层原理: 使用 JDK 动态代理 或 CGLIB 生成代理类,这就是 代理模式 的实际应用。
五、模板方法模式(Template Method Pattern)
🎯 模式说明:
定义一个操作中的算法骨架,将某些步骤延迟到子类或具体实现中。
✅ 代码示例:JdbcTemplate(简化 JDBC 操作)
@Repository
public class UserRepository {@Autowiredprivate JdbcTemplate jdbcTemplate;public List<String> findAllUsernames() {return jdbcTemplate.queryForList("SELECT username FROM users",String.class);}
}
说明:
JdbcTemplate
封装了 JDBC 的连接获取、异常处理、资源释放等重复逻辑,开发者只需要关注 SQL 语句和结果处理,这就是 模板方法模式 的典型应用。
六、观察者模式(Observer Pattern)
🎯 模式说明:
定义对象间的一对多依赖关系,当一个对象状态发生变化时,所有依赖它的对象都会收到通知。
✅ 代码示例:Spring 的事件机制(ApplicationEvent / Listener)
- 定义事件:
public class UserRegisteredEvent extends ApplicationEvent {private String username;public UserRegisteredEvent(Object source, String username) {super(source);this.username = username;}public String getUsername() {return username;}
}
- 发布事件:
@Service
public class UserService {@Autowiredprivate ApplicationContext applicationContext;public void registerUser(String username) {System.out.println("用户注册: " + username);// 发布事件applicationContext.publishEvent(new UserRegisteredEvent(this, username));}
}
- 监听事件:
@Component
public class UserRegisteredListener implements ApplicationListener<UserRegisteredEvent> {@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {System.out.println("收到用户注册事件,用户名:" + event.getUsername());}
}
说明: 这是典型的 观察者模式,事件发布者不关心谁监听,监听者自动收到通知,实现解耦。
七、适配器模式(Adapter Pattern)
🎯 模式说明:
将一个类的接口转换成客户端所期望的另一个接口。
✅ 代码示例:Spring MVC 中的 HandlerAdapter
虽然我们一般不直接使用,但 Spring MVC 内部使用 HandlerAdapter 将不同类型的 Controller(如 @Controller
、HttpRequestHandler
)适配成统一的处理逻辑。
🔍 简化理解:
- 你写了一个
@RestController
,但底层 Spring 需要通过适配器将其方法调用与 HTTP 请求处理逻辑对接起来。 - 每种 Controller 类型都有对应的 Adapter 实现,如
RequestMappingHandlerAdapter
。
说明: 这是典型的 适配器模式,用于统一处理不同接口实现。
✅ Spring MVC 中的 HandlerAdapter(处理 HTTP 请求的核心)
在 Spring MVC 中,开发者通常使用 @Controller
或 @RestController
定义控制器方法,例如:
@RestController
@RequestMapping("/user")
public class UserController {@GetMapping("/{id}")public String getUser(@PathVariable Long id) {return "User " + id;}
}
但是,Spring 底层并不是直接调用你的 Controller 方法,而是通过一个中间层——HandlerAdapter
(处理器适配器),将不同类型的处理器(如基于注解的 @Controller
、传统的 HttpRequestHandler
、Servlet
等)适配成统一的处理逻辑,最后执行目标方法并返回结果。
📌 适配器模式在 Spring MVC 中的体现(源码级别简化理解)
虽然我们一般不会自己去实现 HandlerAdapter,但 Spring 提供了多个内置的适配器,比如:
RequestMappingHandlerAdapter
:处理@RequestMapping
注解的控制器方法(也就是我们最常用的@RestController
/@Controller
)。HttpRequestHandlerAdapter
:处理实现了HttpRequestHandler
接口的处理器。SimpleControllerHandlerAdapter
:处理实现了Controller
接口的旧式控制器。
📌 适配器模式在这里的作用总结:
角色 | 说明 | 对应 Spring 中的实现 |
---|---|---|
Handler(处理器) | 实际处理请求的对象,但类型可能不同 | @Controller 方法、HttpRequestHandler 等 |
HandlerAdapter(适配器) | 将不同处理器适配成统一的调用方式 | RequestMappingHandlerAdapter 、HttpRequestHandlerAdapter |
Dispatcher(调度器) | 根据处理器类型选择合适的适配器来执行 | DispatcherServlet |
Spring MVC 的核心调度逻辑中,正是通过多个 HandlerAdapter 实现了对不同 Controller 类型的适配,这就是适配器模式的典型应用。
✅ 总结一句话:
在 Spring MVC 中,HandlerAdapter 是适配器模式的典型应用,它让不同类型的处理器(如注解控制器、传统控制器)能够通过统一的接口被调度和执行,从而实现灵活、可扩展的请求处理机制。
八、策略模式(Strategy Pattern)
🎯 模式说明:
定义一组算法,将每个算法封装起来,并使它们可以互相替换。
✅ 代码示例:Spring 事务管理策略
Spring 根据不同的数据源,使用不同的 PlatformTransactionManager 实现类,如:
DataSourceTransactionManager
(用于 JDBC)HibernateTransactionManager
(用于 Hibernate)JpaTransactionManager
(用于 JPA)
Spring 会根据你配置的事务管理器,动态选择合适的策略来管理事务。
✅ 配置示例:
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource); // 选择 JDBC 事务策略
}
说明: 不同的数据访问技术,使用不同的策略实现,但对外提供统一的编程模型,这就是 策略模式。
九、原型模式(Prototype Pattern)
🎯 模式说明:
每次获取 Bean 时都创建一个新的实例,而不是复用。
✅ 代码示例:设置 Bean 为 Prototype 作用域
@Component
@Scope("prototype") // 每次获取新实例
public class PrototypeBean {private UUID id = UUID.randomUUID();public UUID getId() {return id;}
}
测试代码:
@Autowired
private ApplicationContext context;PrototypeBean bean1 = context.getBean(PrototypeBean.class);
PrototypeBean bean2 = context.getBean(PrototypeBean.class);System.out.println(bean1.getId()); // UUID1
System.out.println(bean2.getId()); // UUID2,不一样!
说明: 每次调用
getBean()
都生成新的对象,适用于有状态的 Bean。
🔚 总结:Spring 常用设计模式与代码对照表
设计模式 | 说明 | Spring 中的体现 | 代码关键词/注解 |
---|---|---|---|
IoC / DI | 控制反转与依赖注入 | Bean 由 Spring 管理,自动注入 | @Autowired , @Service |
工厂模式 | 统一创建对象 | ApplicationContext , BeanFactory | context.getBean() |
单例模式 | 一个类只有一个实例 | 默认 Bean 作用域 | 无特别配置,就是单例 |
代理模式 | 方法增强、AOP 实现 | @Transactional , AOP 代理 | @Aspect , @Around |
模板方法模式 | 封装固定流程 | JdbcTemplate , RestTemplate | jdbcTemplate.query(...) |
观察者模式 | 事件驱动 | ApplicationEvent , ApplicationListener | 事件发布与监听 |
适配器模式 | 接口转换 | HandlerAdapter (Spring MVC) | 适配不同 Controller |
策略模式 | 算法替换 | 事务管理策略、HandlerMapping | PlatformTransactionManager |
原型模式 | 每次获取新对象 | @Scope("prototype") | 每次 getBean() 不一样 |