03-Spring AOP中的设计模式

Spring AOP中的设计模式分析

1. 代理模式 (Proxy Pattern)

源码分析:

Spring AOP通过使用JDK动态代理或CGLIB字节码生成来创建代理对象,以实现切面功能。JDK动态代理用于代理实现了接口的类,而CGLIB用于代理没有实现接口的类。以下是相关源码的简要分析:

  • JDK动态代理
    Spring使用Proxy类和InvocationHandler接口来创建代理对象。

    public class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
        private final AdvisedSupport advised;
    
        public JdkDynamicAopProxy(AdvisedSupport config) {
            this.advised = config;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, advised.getTargetSource().getTarget(), method, args, advised.getInterceptorsAndDynamicInterceptionAdvice(method, advised.getTargetClass()));
            return invocation.proceed();
        }
    }
    
    • 分析代码片段的功能
      JdkDynamicAopProxy类实现了InvocationHandler接口,通过invoke方法实现代理逻辑。invoke方法调用ReflectiveMethodInvocation对象的proceed方法,该方法会按顺序执行所有拦截器和目标方法。
  • CGLIB代理
    Spring使用CGLIB库生成子类来实现代理。

    public class CglibAopProxy implements AopProxy {
        private final AdvisedSupport advised;
    
        public CglibAopProxy(AdvisedSupport advised) {
            this.advised = advised;
        }
    
        @Override
        public Object getProxy(ClassLoader classLoader) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.advised.getTargetSource().getTargetClass());
            enhancer.setCallback(new DynamicAdvisedInterceptor(this.advised));
            return enhancer.create();
        }
    }
    
    private static class DynamicAdvisedInterceptor implements MethodInterceptor {
        private final AdvisedSupport advised;
    
        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }
    
        @Override
        public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            MethodInvocation invocation = new CglibMethodInvocation(target, method, args, proxy, advised.getInterceptorsAndDynamicInterceptionAdvice(method, advised.getTargetClass()));
            return invocation.proceed();
        }
    }
    
    • 分析代码片段的功能
      CglibAopProxy类通过CGLIB的Enhancer创建目标类的子类,并将DynamicAdvisedInterceptor设置为回调。DynamicAdvisedInterceptor实现了MethodInterceptor接口,其intercept方法会按顺序执行所有拦截器和目标方法。

设计思想:

代理模式通过代理对象控制对目标对象的访问,可以在目标对象的方法调用前后执行一些额外的操作,而不需要修改目标对象本身的代码。

解决的问题:

  • 透明代理:客户端无需知道目标对象是否被代理,只需要使用代理对象即可。
  • 灵活扩展:在不改变目标对象的情况下,通过代理对象可以添加额外的功能,如日志记录、事务管理等。

优缺点:

  • 优点
    • 透明性:客户端对代理对象的使用与对目标对象的使用一致,增加了透明性。
    • 灵活性:可以动态地为目标对象添加功能,增强了代码的灵活性和可扩展性。
  • 缺点
    • 性能开销:代理对象的创建和方法调用有一定的性能开销,特别是在使用CGLIB时。
    • 复杂性:引入代理模式会增加系统的复杂性,特别是代理链较长时。
2. 装饰模式 (Decorator Pattern)

源码分析:

AOP切面可以看作是在不改变目标对象的情况下,动态地为目标对象添加职责。在Spring AOP中,MethodInterceptor可以用来实现装饰模式。以下是相关源码的简要分析:

public class MethodInvocation {
    private final List<MethodInterceptor> interceptors;
    private int currentInterceptorIndex = -1;

    public Object proceed() throws Throwable {
        if (this.currentInterceptorIndex == this.interceptors.size() - 1) {
            return this.method.invoke(this.target, this.arguments);
        }
        MethodInterceptor interceptor = this.interceptors.get(++this.currentInterceptorIndex);
        return interceptor.invoke(this);
    }
}

public class TransactionInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        TransactionStatus status = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
        Object retVal;
        try {
            retVal = invocation.proceed();
            this.transactionManager.commit(status);
        } catch (Throwable ex) {
            this.transactionManager.rollback(status);
            throw ex;
        }
        return retVal;
    }
}
  • 分析代码片段的功能
    MethodInvocation类的proceed方法会顺序执行所有MethodInterceptor,最终执行目标方法。TransactionInterceptor是一个具体的MethodInterceptor,在目标方法执行前后添加事务管理逻辑。

设计思想:

装饰模式通过一个装饰对象来包裹目标对象,动态地为目标对象添加新的功能,而不改变其接口。

解决的问题:

  • 动态职责:在不改变目标对象的情况下,动态地添加或改变其功能。
  • 职责分离:不同的功能由不同的装饰类实现,职责分离清晰。

优缺点:

  • 优点
    • 灵活性:可以在运行时为对象添加新的功能,增强了代码的灵活性。
    • 职责分离:不同的装饰类负责不同的功能,职责分离明确。
  • 缺点
    • 复杂性:装饰链过长时,会增加代码的复杂性和理解难度。
    • 性能开销:多层装饰会带来额外的性能开销。

总结

Spring AOP模块通过使用代理模式和装饰模式,实现了切面功能的灵活扩展。代理模式通过动态代理为目标对象添加功能,保持了代码的透明性和灵活性。装饰模式通过装饰类为目标对象动态添加职责,实现了职责分离和代码复用。这两种模式的结合,使得Spring AOP能够在不改变目标对象的情况下,实现各种切面功能,增强了代码的可维护性和可扩展性。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值