工厂模式:BeanFactory 的工厂模式实现
工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。
1. 简单工厂模式
java
// 简化的简单工厂示例
public class BeanFactory {
private Map<String, Object> beanMap = new HashMap<>();
public Object getBean(String beanName) {
// 根据 beanName 返回对应的 Bean
return beanMap.get(beanName);
}
public void registerBean(String beanName, Object bean) {
beanMap.put(beanName, bean);
}
}
Spring 中的应用:
BeanFactory接口本身是简单工厂的抽象- 具体实现类(如
DefaultListableBeanFactory)根据 Bean 定义创建对象
2. 工厂方法模式
java
// 工厂方法模式示例
public interface BeanFactory {
Object getBean(String name);
}
public class XmlBeanFactory implements BeanFactory {
private Map<String, BeanDefinition> beanDefinitions;
public Object getBean(String name) {
BeanDefinition definition = beanDefinitions.get(name);
// 根据定义创建 Bean
return createBean(definition);
}
}
Spring 的具体体现:
- 不同
BeanFactory实现类提供不同的 Bean 创建方式 ApplicationContext是BeanFactory的子接口,提供更多功能
3. 抽象工厂模式
java
// 抽象工厂示例
public interface ApplicationContext extends BeanFactory,
ResourcePatternResolver,
ApplicationEventPublisher {
// 扩展了多个工厂的功能
}
// 具体实现
public class ClassPathXmlApplicationContext extends AbstractApplicationContext {
// 实现了完整的 Bean 生命周期管理
}
单例模式:Spring Bean 的单例实现
单例模式是一种创建型设计模式,保证一个类只有一个实例,并提供一个全局访问点。
1. 容器级单例
java
// Spring 单例注册表(简化版)
public class DefaultSingletonBeanRegistry {
// 单例对象缓存池
private final Map<String, Object> singletonObjects =
new ConcurrentHashMap<>(256);
// 获取单例
public Object getSingleton(String beanName) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 双重检查锁定
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = createBean(beanName);
this.singletonObjects.put(beanName, singletonObject);
}
}
}
return singletonObject;
}
}
2. 单例作用域配置
java
// 方式1:XML配置
<bean id="userService" class="com.example.UserService"
scope="singleton"/> <!-- 默认就是 singleton -->
// 方式2:注解配置
@Component
@Scope("singleton") // 或不写,默认就是 singleton
public class UserService {
// ...
}
// 方式3:Java配置
@Configuration
public class AppConfig {
@Bean
@Scope("singleton")
public UserService userService() {
return new UserService();
}
}
3. 与普通单例的区别
| 对比项 | Spring 单例 | 传统单例模式 |
|---|---|---|
| 创建时机 | 容器启动时(非懒加载)或首次请求时(懒加载) | 类加载时或首次调用时 |
| 存储位置 | Spring 容器缓存中 | JVM 静态变量或枚举 |
| 数量限制 | 容器内单例,不同容器不同实例 | JVM 内单例 |
| 配置方式 | 可配置(singleton/prototype) | 代码固定 |
| 生命周期 | 受容器管理,可销毁 | 随 JVM 生命周期 |
代理模式:Spring AOP 的代理实现
代理模式是一种结构型设计模式,为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。
1. JDK 动态代理
java
// 目标接口
public interface UserService {
void saveUser();
}
// 目标类
public class UserServiceImpl implements UserService {
public void saveUser() {
System.out.println("保存用户");
}
}
// JDK 动态代理处理器
public class JdkDynamicProxyHandler implements InvocationHandler {
private Object target; // 目标对象
public JdkDynamicProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("开始事务");
// 调用目标方法
Object result = method.invoke(target, args);
// 后置增强
System.out.println("提交事务");
return result;
}
}
// 创建代理
public class ProxyFactory {
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new JdkDynamicProxyHandler(target)
);
}
}
Spring 中的使用场景:
- 目标类实现了接口
- 事务管理(@Transactional)
- 安全控制(@Secured)
2. CGLIB 动态代理
java
// 目标类(无接口)
public class UserService {
public void saveUser() {
System.out.println("保存用户");
}
}
// CGLIB 方法拦截器
public class CglibMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
// 前置增强
System.out.println("开始事务");
// 调用父类(目标类)方法
Object result = proxy.invokeSuper(obj, args);
// 后置增强
System.out.println("提交事务");
return result;
}
}
// 创建代理
public class CglibProxyFactory {
public static Object createProxy(Class<?> targetClass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
enhancer.setCallback(new CglibMethodInterceptor());
return enhancer.create();
}
}
3. Spring AOP 的选择策略
java
// 简化的 Spring AOP 代理创建逻辑
public class DefaultAopProxyFactory implements AopProxyFactory {
@Override
public AopProxy createAopProxy(AdvisedSupport config) {
// 根据配置决定使用 JDK 代理还是 CGLIB 代理
if (config.isOptimize() ||
config.isProxyTargetClass() ||
hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass.isInterface() ||
Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new CglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
}
4. Spring AOP 的配置方式
java
// 方式1:注解配置
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制使用 CGLIB
public class AopConfig {
}
// 切面定义
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("方法执行前:" + joinPoint.getSignature().getName());
}
}
// 方式2:XML配置
<aop:config proxy-target-class="true">
<aop:aspect ref="loggingAspect">
<aop:before pointcut="execution(* com.example.service.*.*(..))"
method="logBefore"/>
</aop:aspect>
</aop:config>
5. 代理模式在 Spring 的其他应用
- 声明式事务管理 :
@Transactional注解通过代理实现 - Spring Security:安全拦截通过代理实现
- 缓存抽象 :
@Cacheable注解通过代理实现缓存逻辑 - 远程调用:RMI、HTTP Invoker 等通过代理封装
总结对比
| 特性 | JDK 动态代理 | CGLIB 代理 |
|---|---|---|
| 目标要求 | 必须实现接口 | 类即可(不能是 final) |
| 性能 | 调用时反射,较慢 | 生成子类,调用较快 |
| 生成方式 | 运行时生成接口实现类 | 运行时生成目标类的子类 |
| Spring 默认 | 有接口时使用 | 无接口或配置 proxyTargetClass=true 时使用 |
Spring 通过这些设计模式的巧妙结合,实现了 IoC 容器、AOP、声明式事务等核心功能,提供了灵活且强大的企业级开发框架。
责任链模式
责任链模式是一种行为型设计模式,它允许多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
解耦发送者和接收者:发送者不需要知道哪个对象会处理请求
动态组合处理链:可以动态地添加、删除或重新排序处理者
避免请求者和处理者紧耦合。
在Spring中,例如拦截器链(HandlerInterceptor)就是纯责任链,因为如果某个拦截器的preHandle返回false,则链终止,且只有部分拦截器(在返回false之前的那些)的preHandle被调用,而postHandle和afterCompletion则只有符合条件的拦截器才会执行(且每个拦截器只执行一次)。而过滤器链(Filter)则是不纯责任链,因为每个过滤器都会执行doFilter,并且每个过滤器都会执行。
拦截器(Interceptor)的使用
- 创建自定义拦截器,实现 HandlerInterceptor 接口
- 注册拦截器WebConfig implements WebMvcConfigurer
过滤器(Filter)的使用
- 创建自定义过滤器,实现 Filter 接口
- 使用 FilterRegistrationBean 注册过滤器
总结
工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
单例模式:Bean默认为单例模式。
代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
责任链模式:在Spring中,例如拦截器链(HandlerInterceptor)就是纯责任链,因为如果某个拦截器的preHandle返回false,则链终止,且只有部分拦截器(在返回false之前的那些)的preHandle被调用,而postHandle和afterCompletion则只有符合条件的拦截器才会执行(且每个拦截器只执行一次)。而过滤器链(Filter)则是不纯责任链,因为每个过滤器都会执行doFilter,并且每个过滤器都会执行。