前言
上一篇【Spring源码解析AOP(二)AOP后置处理器的工作】说到处理AOP的后置处理器即将创建真实Bean的代理对象,用于使用AOP功能,本篇就接着上次说到的createProxy()方法继续,看看Spring是怎么为一个原生对象创建一个代理的。更多Spring内容进入【Spring解读系列目录】。
为创建代理做准备
接着上篇进入createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean))方法,注意这个时候已经把bean的类信息,类名,过滤器,以及bean对象传递进去了。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//创建一个代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
//判断是不是需要CGLIB代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true); //需要就设置为true
}
else { //否则就使用JDK动态代理
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//把切面信息放到这里来
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//初始化proxyFactory的各种信息,before,after,around,具体内容之类的。为了创建代理使用的
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//得到代理,那么代理对象就是在这里被创建的
return proxyFactory.getProxy(getProxyClassLoader());
}
在这个方法里进行了一系列的设置,传递方法,是不是使用CGLIB动态代理,切面信息等等内容给代理工厂,最终在最后面的proxyFactory.getProxy(getProxyClassLoader());把代理创建出来。
选择动态代理的方式
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
这里createAopProxy()是在AopProxy接口中的方法,它有三个实现:CglibAopProxy、JdkDynamicAopProxy、和ObjenesisCglibAopProxy具体是哪个实现要看这个方法里面的选择。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
继续进入createAopProxy()方法,看怎么选择实现类。这个方法的实现是在DefaultAopProxyFactory#createAopProxy()这里。
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.");
}
//如果目标对象是一个接口,或者是一个代理,Spring仍然会使用JDK动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {//如果什么都不开启,使用JDK动态代理,那么上一层调用的就是JdkDynamicAopProxy里面的getProxy(),直接去里面看
return new JdkDynamicAopProxy(config);
}
}
首先进入到第一个if语句里: config.isOptimize()条件这个值在xml里面可以配置,意思为 是否对生产代理策略使用优化,默认为false;config.isProxyTargetClass()条件在@EnableAspectJAutoProxy(proxyTargetClass = true)这里设置,意思是是否开启CGLIB代理,默认为false;hasNoUserSuppliedProxyInterfaces(config) 条件,意为是否存在代理接口,默认为fasle;如果直接开启Spring,而不做任何操作,整个if条件为false,直接到else使用JDK动态代理。最终会看到其实最后如果不是JDK动态代理,就是CGLIB动态代理生了AOP的代理对象。而之所以说Spring默认的就是JDK动态代理,也是因为这里。如果Spring一切配置都是默认的话,就会走到JdkDynamicAopProxy这个类去生成AOP代理。
JDK动态代理生成AOP
如果由JDK最终生成,那么最终将会由JdkDynamicAopProxy#getProxy(ClassLoader)方法去实现这个代理。看到下面最后return的代码,笔者相信任何对代理熟悉的同学都知道,这里生成了代理共给AOP使用。
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//看这里Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);,做了一个代理对象。
//所以说Spring底层用的是动态代理
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
CGLIB动态代理生成AOP
说完JDK,开启了CGLIB后这里又是怎么做的呢?进入CglibAopProxy#getProxy(ClassLoader)。
public Object getProxy(@Nullable ClassLoader classLoader) {
/**略去代理对象的配置**/
//关键在这里
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
方法很长,简化一下。最终落脚点就在createProxyClassAndInstance(enhancer, callbacks);这个方法里。首先尝试从缓存中拿,如果拿不到,就使用构造方法的newInstance()反射生成一个代理返回出去。
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try { //企图从cache中拿
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
catch (Throwable ex) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", ex);
}
}
if (proxyInstance == null) {
// Regular instantiation via default constructor...
try { //如果拿不到使用构造方法反射生成代理
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
}
catch (Throwable ex) {
throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
"and regular proxy instantiation via default constructor fails as well", ex);
}
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
总结
到此SpringAOP代理的生成就结束了,中间还有忽略了Bean的生成过程,这一过程太过于复杂,等笔者捋顺了在写帖子发出来吧。那么最后总结一下这三篇的内容:首先开启AOP,引入执行AOP动态代理的后置处理器,然后Spring容器负责把bean创建出来(new出来),由AOPBeanPostProcessor负责收集Bean实例、切面等等信息传给代理选择器,最后根据配置选除合适的代理处理类,把AOP动态代理创建出来,到此SpringAOP动态代理完成,撒花。

本文解析了Spring AOP如何根据配置选择JDK或CGLIB动态代理生成代理对象的过程。详细介绍了createProxy()方法中代理工厂的配置及代理对象的创建细节。
2704

被折叠的 条评论
为什么被折叠?



