Spring-理解AOP编程
动态代理这部分我有过一篇博客介绍:动态代理,想深入了解的朋友可以看一看,再回顾一下,春季中如何区分采用JDK动态代理和CGLIB动态代理:
- 如果目标对象的实现类实现了接口,Spring AOP将会采用JDK动态代理来生成AOP代理类;
- 如果目标对象的实现类没有实现接口,Spring AOP将会采用CGLIB来生成AOP代理类
将下载编译好的Spring的AOP包中的源码打开,如下图所示
相应的源码可以在Github上面,然后用工具编译成project文件,再导入eclipse里面来阅读,网上有相应的方法。Spring AOP使用类org.springframework.aop.framework.ProxyFactory进行织入,找到ProxyFactory对应的相关内容,然后整理如下类图
春天代理类如何生成
调用方法步骤可以如下所示:
新建一个目标,目标使我们需要操作的目标定义一个代理工厂,可以是ProxyFactory里或者ProxyFactryBean是两种方法,豆顾名思义,采用的弹簧中的IOC机制,而ProxyFactory类方法则可以直接得到
加入通知
得到代理实例,通过getproxy()方法
先看ProxyFactory里是如何得到代理类的
找到ProxyFactory里中的getProxy()方法;
public Object getProxy() {
return createAopProxy().getProxy();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
实现它获得一个用来产生代理的实例,createAopProxy()方法返回AopProxy,然后再调用getProxy()方法产生具体的代理对象,这里下面再细讲,因为在ProxyFactoryBean中也用到了一样的父类。
得到了一个AopProxy之后,再利用AopProxy的方法,根据条件获得一个用来产生代理的实例,要么是JDK动态代理生成,要么是CGLIB代理生成。
ProxyFactoryBean的是如何获得代理类的
找到ProxyFactoryBean方法,ProxyFactoryBean是在Spring IoC环境中,创建AOP应用的最底层方法,从中,可以看到一条实现AOP的基本线索。借助如上类图,看看AOP代理类是如何产生的(回顾下动态代理中的代理类生成方法)
先看看ProxyFactryBean是中的的getObject方法
为什么要先看的getObject方法呢:如果容器中的某个对象持有某个的FactoryBean的引用,它取得的不是的FactoryBean本身,而是的FactoryBean的的getObject()方法所返回的对象所以,如果容器中某个对象依赖于ProxyFactryBean是,那么它将会使用到的ProxyFactoryBean的的getObject()方法所返回的代理对象
继续跟踪getSingletonInstance()方法,这个地方可以看出点东西
@Override
public Object getObject() throws BeansException {
initializeAdvisorChain(); //初始化通知器
if (isSingleton()) {
return getSingletonInstance();//根据定义生成单例的Proxy
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance(); //这里根据定义生成prototype的Proxy
}
}
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();//返回被 代 理的 目标对象
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
//从targetSource中获取目标对象的Class
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
//这里设置代理对象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// 初始化共享的单例
super.setFrozen(this.freezeProxy);
//这里会使用ProxyFactory来生成需要的Proxy
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
这里看看setFrozen()和createAopProxy()方法,调用的是ProxyFactryBean是上一层接口ProxyCreatorSupport中的方法(看类图),
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this); //这里借助了AopProxyFactory
}
下面这很重要,getAopProxyFactory()方法,
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
虽然返回的是aopProxyFactory但是我们如果追踪到构造函数中,我们发现其实用的是new DefaultAopProxyFactory();
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
继续追踪到DefaultAopProxyFactory中,找到createAopProxy()方法,终于真相大白,如下
@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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
可以看到其中的代理对象可以由JDK或者CGLIB来生成的,JdkDynamicAopProxy类和Cglib2AopProxy都实现的是AopProxy的接口,上面的这些逻辑就是要判断采用两种动态代理中的那一种,具体的规则可以参考最上面的介绍。到了这里,可能对JDK动态代理有点心动,毕竟动态代理中接触过了,如下是JdkDynamicAopProxy中实现代理的方法-getproxy()方法
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//根据advised 中 的 配 置信息,将proxy需要代 理的接口放入proxiedInterfaces 中
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//下面这个方法眼熟吧,哈哈 没错就是JDK中的动态代理经典方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
用代理包装目标之后,通过ProxyFactoryBean得到对其方法的调用就被代理拦截了,ProxyFactoryBean的getObject()方法得到的实际上是一个代理了,目标对象已经被封装了。对ProxyFactoryBean这个工厂bean而言,其生产出来的对象是封装了目标对象的代理对象
总结
上面讲了怎么多,简单回顾下代理对象是如何生成的
1,上面讲到了两种生成代理对象的方法,一种是通过ProxyFactory类,一种是通过ProxyFactoryBean的。第一种获取比较简单,但是需要手工的进行写代码,而第二种是通过弹簧的IOC机制来控制豆的生成。
2,无论是ProxyFactory里或者ProxyFactryBean是都是要通过createAopProxy()。getProxy()来获取相应的代理对象,而通过ProxyFactory里比较直接,上面重点介绍的是通过ProxyFactryBean是获得代理。
3,首先,找到的ProxyFactoryBean的的getObject方法,为什么?(主要是跟豆容器中的getObject能返回代理对象)
4,其次调用getSingletonInstance(),在getSingletonInstance方法中引入了超级中的方法,超是指ProxyCreatorSupport,这里ProxyCreatorSupport是ProxyFactryBean是和ProxyFactory里的父类,已经做了很多工作,只需在ProxyFactryBean是的的getObject()方法中通过父类的createAopProxy()取得相应的AopProxy。
5,跟踪createAopProxy方法,追踪到了ProxyCreatorSupport中,然后,借助了AopProxyFactory,此时得到的aopProxyFactory,在构造函数中已经定义为新的DefaultAopProxyFactory()
如图6所示,进入DefaultAopProxyFactory中,找到createAopProxy方法,在这里判断是调用JDK动态或者CGLIB动态中的一种。

浙公网安备 33010602011771号