在上篇文章SpringAop源碼分析(基於註解)二:篩選通知器中,咱們對AOP中通知的建立和篩選過程進行了分析,本章咱們一塊兒來看看,AOP是怎麼建立代理對象的。java
咱們先回到Bean初始化以後,調用BeanPostProcessor後置處理器的地方。緩存
//AbstractAutoProxyCreator.java
//在Bean初始化以後回調
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//判斷緩存中是否有
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 沒有,爲 bean 生成代理對象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
複製代碼
wrapIfNecessary代碼:ide
//AbstractAutoProxyCreator.java
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
/* * 若是是基礎設施類(Pointcut、Advice、Advisor 等接口的實現類),或是應該跳過的類, * 則不該該生成代理,此時直接返回 bean */
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
<1> // 返回匹配當前 bean 的全部的通知器 advisor、advice、interceptor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 核心!建立代理對象
<2> 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;
}
複製代碼
上篇文章咱們主要分析的是<1>處代碼,如今有了合適的通知器,咱們要爲當前Bean建立代理對象,把通知器(Advisor)所持有的通知(Advice)織入到 bean 的某些方法先後。源碼分析
看代碼:post
//AbstractAutoProxyCreator.java
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);
//proxyTargetClass是 @EnableAspectJAutoProxy 的屬性之一
//true -> 強制使用CGLIB代理
if (!proxyFactory.isProxyTargetClass()) {
//false
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
//檢測 beanClass 是否實現了接口,若未實現,則將
//proxyFactory 的成員變量 proxyTargetClass 設爲 true
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//封裝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());
}
複製代碼
這裏咱們主要看下核心邏輯:優化
這裏的 isProxyTargetClass() 其實就是咱們前面用的註解@EnableAspectJAutoProxy
的屬性之一,當其爲true時,強制使用CGLIB代理。ui
下面咱們接着看建立代理的代碼:this
//ProxyFactory.java
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
複製代碼
這段方法有兩個方法調用:lua
咱們先來看下createAopProxy():spa
//DefaultAopProxyFactory.java
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//if中的3個條件
//一、 config.isOptimize() - 是否須要優化
//二、 config.isProxyTargetClass() - 檢測 proxyTargetClass 的值
//三、 hasNoUserSuppliedProxyInterfaces(config) - 目標 bean 是否實現了接口
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)) {
//建立JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
}
//建立CglibAopProxy
return new ObjenesisCglibAopProxy(config);
}
else {
//建立JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
}
}
複製代碼
最終調用的是DefaultAopProxyFactory#createAopProxy(...)
方法,經過這個方法建立AopProxy 的實現類,如: JdkDynamicAopProxy,而後根據這個實現類再建立代理對象。
咱們以JdkDynamicAopProxy爲例,看下getProxy(classLoader)
:
//JdkDynamicAopProxy.java
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 調用 newProxyInstance 建立代理對象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
複製代碼
直接看代碼最後一行,最終調用 Proxy.newProxyInstance 方法建立代理對象。