上一篇《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);
}
}