源碼通透-spring-AOP-5-AspectJAwareAdvisorAutoProxyCreator
spring源碼版本:spring5.0
jdk: 1.8
我保存的源碼地址:https://gitee.com/paincupid/spring-framework.git
或者官網地址:https://github.com/spring-projects/spring-framework.git
更多源碼文章:https://github.com/arthur-dy-lee/arthur-dy-lee-note
文章目錄
- 源碼通透-spring-AOP-5-AspectJAwareAdvisorAutoProxyCreator
- 作用
- 一、AspectJAwareAdvisorAutoProxyCreator類繼承關係
- 二、AbstractAutoProxyCreator#postProcessAfterInitialization()-創建代理的入口函數
- 三、 AbstractAutoProxyCreator#wrapIfNecessary() 如果bean需要被代理,包裝bean返回代理對象
- 四、 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 獲取可用的切面advices和Advisors
- 五、AbstractAutoProxyCreator#createProxy 創建AOP代理
- 六、 createAopProxy:JDK代理或CGLIB代理
- 6.1 ProxyCreatorSupport#createAopProxy 創建AOP代理:使用JDK或CGLIB
- 6.2 DefaultAopProxyFactory#createAopProxy 決定使用cglib還是jdk代理
- 七、 getProxy 選擇對應的getProxy方法創建代理對象
作用
主要爲AspectJ
切面服務。具體的針對如何創建代理,是在父類中(AbstractAutoProxyCreator#createProxy
)實現。
AbstractAutoProxyCreator
實現了BeanPostProcess
接口,所以在創建時,調用``postProcessAfterInitialization`方法
1、獲取可用的切面advice,從beanFactory中查找可用的切面
2、由ProxyFactory來創建代理對象。默認是採用JDK靜態代理,對beanClass爲非接口實現類採取CGLIB動態代理
一、AspectJAwareAdvisorAutoProxyCreator類繼承關係
SmartInstantiationAwareBeanPostProcessor
是beanPostProcessor接口的子類,spring在實例化bean對象的時候會調用beanPostProcessor的公有接口。
BeanPostProcessor,針對所有Spring上下文中所有的bean,可以在配置文檔applicationContext.xml中配置一個BeanPostProcessor,然後對所有的bean進行一個初始化之前和之後的代理。
BeanPostProcessor接口中有兩個方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前執行, postProcessAfterInitialization方法在bean初始化之後執行。
afterPropertiesSet 和init-method之間的執行順序是afterPropertiesSet 先執行,init-method 後執行。從BeanPostProcessor的作用,可以看出最先執行的是postProcessBeforeInitialization,然後是afterPropertiesSet,然後是init-method,然後是postProcessAfterInitialization。
postProcessAfterInitialization是bean對象被實例化的最後一步操作的
bean實例化順序,看下面代碼:
AbstractAutowireCapableBeanFactory#initializeBean
1、applyBeanPostProcessorsBeforeInitialization–>beanProcessor.postProcessBeforeInitialization
2、invokeInitMethods(beanName, wrappedBean, mbd); -->
((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);
3、applyBeanPostProcessorsAfterInitialization --> beanProcessor.postProcessAfterInitialization(result, beanName);
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
二、AbstractAutoProxyCreator#postProcessAfterInitialization()-創建代理的入口函數
postProcessAfterInitialization方法主要調用順序
AbstractAutoProxyCreator#postProcessAfterInitialization 入口類
-wrapIfNecessary 得到可用的切面,並緩存起來
– AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
— findEligibleAdvisors
----1.findCandidateAdvisors查找所有的切面
----- AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
------ BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans 查找接口類型爲Advisor的
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);…
advisors.add(this.beanFactory.getBean(name, Advisor.class));
advisors.add(this.beanFactory.getBean(name, Advisor.class));
----2.findAdvisorsThatCanApply在所有的切面有,查找可用切面
----- AopUtils#findAdvisorsThatCanApply
------ AopUtils#canApply
------- BeanFactoryTransactionAttributeSourceAdvisor#getPointcut 如果是事務類的會進入到BeanFactoryTransactionAttributeSourceAdvisor
AbstractAutoProxyCreator#postProcessAfterInitialization()
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 1、如果之前調用過getEarlyBeanReference獲取包裝目標對象到AOP代理對象(如果需要),則不再執行
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//2、包裝目標對象到AOP代理對象(如果需要)
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
getEarlyBeanReference
和postProcessAfterInitialization
是二者選一的,而且單例Bean
目標對象只能被增強一次
三、 AbstractAutoProxyCreator#wrapIfNecessary() 如果bean需要被代理,包裝bean返回代理對象
wrapIfNecessary 裏面就2個重要方法:
1、getAdvicesAndAdvisorsForBean
2、createProxy
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance //被代理的bean實例
* @param beanName the name of the bean //bean名稱
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//通過TargetSourceCreator進行自定義TargetSource不需要包裝
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不應該被增強對象不需要包裝
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//Advice/Advisor/AopInfrastructureBean接口的beanClass不進行代理以及對beanName爲aop內的切面名也不進行代理,此處可查看子類複寫的sholdSkip()方法
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
//獲取可用的切面advice,並創建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 將cacheKey添加到已經被增強列表,防止多次增強
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;
}
從類繼承結構上看,AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator都繼承了:AbstractAutoProxyCreator。AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator都有getAdvicesAndAdvisorsForBean方法,下面且看AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator有兩個子類
-
一個是BeanNameAutoProxyCreator,它是基於bean名字的自動代理類。 它會給spring容器中bean名字與指定名字匹配的bean自動創建代理。其中匹配的規則定義在PatternMatchUtils.simpleMatch()方法中。注意:若需要給某個FactoryBean創建代理,可以在bean名字前面加上&.
-
第二類是AbstractAdvisorAutoProxyCreator,相對BeanNameAutoProxyCreator而言,它更爲強大,它會自動獲取spring容器中註冊的所有的Advisor類(除了子類中isEligibleAdvisorBean()方法指定的不滿足條件的Advisor除外。),然後自動給spring容器中滿足Advisor中pointCut創建代理。
DefaultAdvisorAutoProxyCreator是默認實現,默認會自動代理所有的Advisor,當然也可以通過設置usePrefix和advisorBeanNamePrefix來過濾部分advisor
AspectJAwareAdvisorAutoProxyCreator用於支持AspectJ方式的自動代理。
四、 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 獲取可用的切面advices和Advisors
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
/**
* Find all eligible Advisors for auto-proxying this class.
* @param beanClass the clazz to find advisors for
* @param beanName the name of the currently proxied bean
* @return the empty List, not {@code null},
* if there are no pointcuts or interceptors
* @see #findCandidateAdvisors
* @see #sortAdvisors
* @see #extendAdvisors
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//Find all candidate Advisors to use in auto-proxying.
//在自動代理中,查找所有advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//Search the given candidate Advisors to find all Advisors that can apply to the specified bean.
//在所有的advisors中查找符合條件的advisors
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findCandidateAdvisors()方法有2個實現方法:
- AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
- AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator重寫了findCandidateAdvisors()
AnnotationAwareAspectJAutoProxyCreator
註解AOP解析,可以看這篇文章:https://blog.csdn.net/heroqiang/article/details/79037741
下面看AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
findCandidateAdvisors會在beanFactory中查找所有的Advisor,調用BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans
BeanFactoryUtils.beanNamesForTypeIncludingAncestors()方法,查找實現接口Advisor的實現類,其中BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor都是Advisor的實現類,在事務AOP時用到。
/**
* Find all eligible Advisor beans in the current bean factory,
* ignoring FactoryBeans and excluding beans that are currently in creation.
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
//查找實現接口Advisor的類,其中BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor都是Advisor的實現類,在事務AOP時用到。
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
List<Advisor> advisors = new LinkedList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
//....
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
}
return advisors;
}
五、AbstractAutoProxyCreator#createProxy 創建AOP代理
/**
* Create an AOP proxy for the given bean.
* @param beanClass the class of the bean
* @param beanName the name of the bean
* @param specificInterceptors the set of interceptors that is
* specific to this bean (may be empty, but not null)
* @param targetSource the TargetSource for the proxy,
* already pre-configured to access the bean
* @return the AOP proxy for the bean
* @see #buildAdvisors
*/
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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//是否採用動態代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
//Check the interfaces on the given bean class and apply them to the ProxyFactory, if appropriate.
// 查看beanClass對應的類是否含有InitializingBean.class/DisposableBean.class/Aware.class接口,以及groovy.lang.GroovyObject,.cglib.proxy.Factory,.bytebuddy.MockAccess。無則採用靜態代理,有則採用動態代理
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());
}
5.1 創建 DefaultAopProxyFactory
當創建ProxyFactory
時,因爲它繼承了ProxyCreatorSupport
,所以會先調用父親的構造函數,這時會創建DefaultAopProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
public class ProxyFactory extends ProxyCreatorSupport
public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory();}
proxyFactory#getProxy() 根據proxyFactory中的設置參數,創建代理對象
這裏的proxyFactory就是DefaultAopProxyFactory
/**
* Create a new proxy according to the settings in this factory.
* <p>Can be called repeatedly. Effect will vary if we've added
* or removed interfaces. Can add and remove interceptors.
* <p>Uses the given class loader (if necessary for proxy creation).
* @param classLoader the class loader to create the proxy with
* (or {@code null} for the low-level proxy facility's default)
* @return the proxy object
*/
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader); // <---------
}
下面幾章重點分析
createAopProxy().getProxy(classLoader)
六、 createAopProxy:JDK代理或CGLIB代理
6.1 ProxyCreatorSupport#createAopProxy 創建AOP代理:使用JDK或CGLIB
ProxyCreatorSupport#createAopProxy
時,getAopProxyFactory()
是指 DefaultAopProxyFactory
,所以getAopProxyFactory().createAopProxy
是會調用DefaultAopProxyFactory#createAopProxy
/**
* Subclasses should call this to get a new AOP proxy. They should <b>not</b>
* create an AOP proxy with {@code this} as an argument.
*/
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
/**
* Return the AopProxyFactory that this ProxyConfig uses.
*/
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
6.2 DefaultAopProxyFactory#createAopProxy 決定使用cglib還是jdk代理
默認是採用JDK代理,對beanClass爲非接口實現類採取CGLIB動態代理。
碰到以下三種情況使用CGLIB
- ProxyConfig的isOptimize方法爲true,這表示讓Spring自己去優化。可以通過 ProxyFactory 的
setOptimize(true)
方法讓 ProxyFactory 啓動優化代理方式,這樣,針對接口的代理也會使用 CglibAopProxy - ProxyConfig的isProxyTargetClass方法爲true,這表示配置了proxy-target-class=”true”
- ProxyConfig滿足hasNoUserSuppliedProxyInterfaces方法執行結果爲true,這表示
<bean>
對象沒有實現任何接口或者實現的接口是SpringProxy接口
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
//...
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
在創建AOP代理後
return createAopProxy().getProxy(classLoader);
再來看下一章的 getProxy
方法。
七、 getProxy 選擇對應的getProxy方法創建代理對象
最後根據jdk還是cglib(ObjenesisCglibAopProxy),選擇對應的getProxy方法創建代理對象。
下面分別看JdkDynamicAopProxy#getProxy 和 CglibAopProxy#getProxy
7.1 JdkDynamicAopProxy#getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
//.....
//拿到所有要代理的接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//尋找這些接口方法裏面有沒有equals方法和hashCode方法,同時都有的話打個標記,尋找結束,equals方法和hashCode方法有特殊處理
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
JDK的代理執行,是在 JdkDynamicAopProxy.invoke()
中執行的,後面執行調用的時候 ,再來分析這個方法。
Proxy#newProxyInstance
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
7.2 CglibAopProxy#getProxy 通過返射構造函數創建代理實例
作用:創建並配置 Enhancer, Enhancer 是CGLIB 主要的操作類,並將DynamicAdvisedInterceptor
攔截器放到callback
因爲
class ObjenesisCglibAopProxy extends CglibAopProxy
但ObjenesisCglibAopProxy 並沒有覆蓋getProxy()方法,所以會調用父親的 CglibAopProxy#getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
//....
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
//創建並配置 Enhancer, Enhancer 是CGLIB 主要的操作類
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//配置超類,代理類實現的接口,回調方法等
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass); // <--------------- 6.4.1
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks); // <------ 6.4.2
}
7.2.1 CglibAopProxy#getCallbacks 來實現AOP代理的攔截
下面的代碼,我們可以看到創建了一個DynamicAdvisedInterceptor
,它最後,被放到Callbacks裏面。當被代理的方法執行時,會執行DynamicAdvisedInterceptor.intercept()
方法。後面執行調用的時候 ,再來分析這個方法。
在Callback[]中有的攔截器包括:
DynamicAdvisedInterceptor、AdvisedDispatcher、SerializableNoOp、EqualsInterceptor、HashCodeInterceptor。
以及根據exposeProxy屬性,以及是否是靜態對象來決定使用下面哪個攔截器
StaticUnadvisedExposedInterceptor、DynamicUnadvisedExposedInterceptor
StaticUnadvisedInterceptor、DynamicUnadvisedInterceptor
最後將上面這些攔截器放入到callback[]中,返回。
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); //<-----------
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
// 判斷被代理的對象是否是靜態的,如果是靜態的,則將目標對象緩存起來,每次都使用該對象即可,
// 如果目標對象是動態的,則在DynamicUnadvisedExposedInterceptor中每次都生成一個新的
// 目標對象,以織入後面的代理邏輯
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
// 下面兩個類與上面兩個的唯一區別就在於是否使用AopContext暴露生成的代理對象
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice <-----DynamicAdvisedInterceptor放入callbacks中
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
7.2.2 createProxyClassAndInstance 創建代理類和代理實例
如果上面createAOP時,創建的是ObjenesisCglibAopProxy
,那麼createProxyClassAndInstance()
會調用ObjenesisCglibAopProxy.createProxyClassAndInstance
方法。
重點,還是將callbacks放到proxyInstance中。
@Override
@SuppressWarnings("unchecked")
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}//.....
}
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());
}//....
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
7.3 StaticUnadvisedExposedInterceptor和DynamicUnadvisedExposedInterceptor區別
StaticUnadvisedExposedInterceptor#intercept
每次從線程副本中取舊的代理,然後執行
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}
finally {
AopContext.setCurrentProxy(oldProxy);
}
}
DynamicUnadvisedExposedInterceptor#intercept
每次取出要代理的目前對象,然後執行。
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = this.targetSource.getTarget();
try {
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
if (target != null) {
this.targetSource.releaseTarget(target);
}
}
}
參考: