上一篇《Spring源码分析之——AOP的原理及初始化细节》讲到AOP的原理和细节,这一篇补充一下动态代理的选择代码细节。
我们知道动态代理分两种,JDK动态代理和Cglib动态代理,那么Spring选用的哪个呢?
右半部分可以看到AopProxy下面有Cglib和JDK两种,至于创建哪种,是左边工厂DefaultAopProxyFactory负责创建的,带着这个图看源码。
1、后置处理器判断是否需要动态代理,判断的依据是Bean是否有配置Advisor;
2、如果需要代理,则构造ProxyFactory对象;
2、通过ProxyFactory对象的父类方法getAopProxyFactory找到AopProxyFactory对象,默认DefaultAopProxyFactory;
3、通过工厂创建实际的代理对象(createAopProxy);
——就这么简单。
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
——从createProxy方法开始看
// 如果需要代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 怎么判断是否需要代理?这里给出了答案:如果有配置Advisers则需要被代理
// 这里开始去找Advice,Advisor,如果配置了,同时当前的Bean符合要求,就要动态代理
// 这里说的符合要求,就是advisor配置的正则表达式是否匹配上
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 有顾问的Bean,cacheKey=被代理BeanName
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// ★★★★★★ 创建代理 ★★★★★★
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 否则,设置不需要顾问
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
protected Object createProxy(
Class beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 首先构造一个ProxyFactory工厂,此工厂提供方法getProxy获取代理对象
// 但其细节是通过其父类先得到AopProxy的工厂,再通过工厂创建AopProxy,再通过AopProxy得到代理对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
org.springframework.aop.framework.ProxyFactory
public Object getProxy(ClassLoader classLoader) {
// createAopProxy是父类方法
// 1、先创建AopProxy
// 2、再创建代理对象
return createAopProxy().getProxy(classLoader);
}
进入父类:
org.springframework.aop.framework.ProxyCreatorSupport
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
/**
* Create a new ProxyCreatorSupport instance.
*/
public ProxyCreatorSupport() {
// 默认实现: DefaultAopProxyFactory
this.aopProxyFactory = new DefaultAopProxyFactory();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 默认AopProxyFactory是:DefaultAopProxyFactory,也只有这一个
return getAopProxyFactory().createAopProxy(this);
}
/**
* Return the AopProxyFactory that this ProxyConfig uses.
*/
public AopProxyFactory getAopProxyFactory() {
// 返回默认的DefaultAopProxyFactory
return this.aopProxyFactory;
}
}
org.springframework.aop.framework.DefaultAopProxyFactory
// 这段代码有前人解释的很好了
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//这段代码用来判断选择哪种创建代理对象的方式
//config.isOptimize() 是否对代理类的生成使用策略优化 其作用是和isProxyTargetClass是一样的 默认为false
//config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 默认为false
//hasNoUserSuppliedProxyInterfaces目标类是否有接口存在 且只有一个接口的时候接口类型不是
//SpringProxy类型
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//上面的三个方法有一个为true的话,则进入到这里
//从AdvisedSupport中获取目标类 类对象
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.");
}
//判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
//如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//配置了使用Cglib进行动态代理 或者目标类没有接口 那么使用Cglib的方式创建代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
//上面的三个方法没有一个为true 那使用JDK的提供的代理方式生成代理对象
return new JdkDynamicAopProxy(config);
}
}