Spring AOP中代理模式的使用

 
    上一篇我的博客《使用aop和注解实现日志记录》中提到了代理模式,那么这篇博客我们好好来理一下设计模式中的“代理模式”是如何在aop中设计和使用的。
 
1:首先,我先解释一下设计模式中“代理模式”的定义
什么是代理模式?
 
代理模式,也叫委托模式,其定义是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。它包含了三个角色:
 
Subject:抽象主题角色。可以是抽象类也可以是接口,是一个最普通的业务类型定义。
 
RealSubject:具体主题角色,也就是被代理的对象,是业务逻辑的具体执行者。
 
Proxy:代理主题角色。负责读具体主题角色的引用,通过真实角色的业务逻辑方法来实现抽象方法,并在前后可以附加自己的操作。
 
用类图来表示的话大概如下:
Spring AOP中代理模式的使用
 
比如:我的上一篇我的博客《使用aop和注解实现日志记录》中,我的核心方法业务逻辑是执行addYaml方法,但是我需要在执行 addYaml方法前后输出关联的日志信息以方便后期出现异常时进行问题定位。
 
这时我可以直接把输出相关日志的代码加在addYaml方法中实现,也可以通过静态代理的方式单独写一个代理类实现addYaml方法,然后进行代理,具体实现见文章最后的参考文献。
考虑到相关的方法前后都要输出相关日志,并且方法众多,我不可能给所有的方法都实现一个代理类。所以Spring Framework框架利用Java反射+拦截的机制用动态代理的方式解决这一个问题。
 
Spring中AOP的实现采用的就是动态代理。
 
先简单放一张《使用aop和注解实现日志记录》中我debug时堆栈中的对象信息。如图我们可以看到methodInvocation={CglibAopProxy……},可以明确看到有使用CGLIB 动态代理。Spring AOP中代理模式的使用
 
而JDK 动态代理和 CGLIB 动态代理均是实现 Spring AOP 的基础。我们可以看下AOP的部分底层源码:
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
 
 
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            // 判断目标类是否是接口或者目标类是否Proxy类型,若是则使用JDK动态代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            // 使用CGLIB的方式创建代理对象
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            // 上面条件都不满足就使用JDK的提供的代理方式生成代理对象
            return new JdkDynamicAopProxy(config);
        }
    }
}
 
 
    源码的判断逻辑并不难,主要是根据目标类是否是接口或者Proxy类型来判断使用哪种代理模式创建代理对象,使用的代理模式正是JDK动态代理和CGLIB 动态代理技术。
 
参考文献:
《设计模式:代理模式是什么,Spring AOP还和它有关系?》https://blog.csdn.net/yeyazhishang/article/details/95460654

Spring AOP中代理模式的使用

上一篇:JAVA链表的创建和使用


下一篇:JAVA环境配置