1、注解工作原理
@EnableAspectJAutoProxy
啟動支援處理标有AspectJ的@Aspect批注的元件,類似于Spring的<aop:aspectj-autoproxy> XML元素中的功能。要在@Configuration類上使用。
注冊BeanName的 internalAutoProxyCreator(AnnotationAwareAspectJAutoProxyCreator.class)的 BeanDefinetion,在執行個體化之前執行傳回代理對象。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* 訓示與基于标準Java接口的代理相反,是否要建立基于子類(CGLIB)的代理。預設為false。
*/
boolean proxyTargetClass() default false;
/**
* 訓示代理應由AOP架構作為ThreadLocal公開,以便通過org.springframework.aop.framework.AopContext類進行檢索。預設情況下為關閉,即不保證AopContext通路将正常進行。
*/
boolean exposeProxy() default false;
}
// AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
// org.springframework.aop.config.AopConfigUtils
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
注冊 AnnotationAwareAspectJAutoProxyCreator
@EnableAspectJAutoProxy
--> @Import(AspectJAutoProxyRegistrar.class)
--> AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
--> AspectJAutoProxyRegistrar.registerBeanDefinitions
-- AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
-- registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
AnnotationAwareAspectJAutoProxyCreator 實作 InstantiationAwareBeanPostProcessor,Instantiation執行個體化之前執行。
graph TB
AnnotationAwareAspectJAutoProxyCreator-->AspectJAwareAdvisorAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator-->AbstractAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator-->AbstractAutoProxyCreator
AbstractAutoProxyCreator-.-SmartInstantiationAwareBeanPostProcessor
AbstractAutoProxyCreator-.-BeanFactoryAware
AbstractAutoProxyCreator-->ProxyProcessorSupport
SmartInstantiationAwareBeanPostProcessor-.-InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor-.-BeanPostProcessor
3、工作流程
3.1 建立和注冊AnnotationAwareAspectJAutoProxyCreator的過程
- 建立ioc容器;
- 注冊配置類,調用refresh()重新整理容器;
- registerBeanPostProcessors(beanFactory); 注冊bean的後置處理器來友善攔截bean的建立;
- 擷取ioc容器已經定義了的需要建立對象的所有BeanPostProcessor;
- 注冊BeanPostProcessorChecker,該日志将在以下情況下記錄資訊消息在BeanPostProcessor執行個體化期間(即當一個bean不适合所有BeanPostProcessor處理。
- 将BeanPostProcessor按照 PriorityOrdered、Ordered、nonOrdered、MergedBeanDefinitionPostProcessor儲存到priorityOrderedPostProcessors、internalPostProcessors、orderedPostProcessorNames、nonOrderedPostProcessorNames 依次注冊;
-
注冊BeanPostProcessor,實際上就是建立BeanPostProcessor對象,儲存在容器中;
建立 internalAutoProxyCreator 的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
- 建立Bean的執行個體;
- populateBean;給bean的各種屬性指派;
- initializeBean:初始化bean;
- invokeAwareMethods():處理Aware接口的方法回調;
- applyBeanPostProcessorsBeforeInitialization():應用後置處理器的postProcessBeforeInitialization();
- invokeInitMethods();執行自定義的初始化方法;
- applyBeanPostProcessorsAfterInitialization();執行後置處理器的postProcessAfterInitialization();
- BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)建立成功;--> initBeanFactory():aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
- 最後重新注冊用于将内部bean檢測為ApplicationListener的後處理器,将其移到處理器鍊的末尾(用于拾取代理等)。
-
把BeanPostProcessor注冊到BeanFactory中;
beanFactory.addBeanPostProcessor(postProcessor);
- finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;建立剩下的非抽象非懶加載單執行個體bean;
-
周遊擷取容器中所有的Bean,依次建立對象getBean(beanName);
preInstantiateSingletons:getBean --> doGetBean --> getSingleton --> singletonFactory.getObject(); --> createBean --> doCreateBean
- createBean
- resolveBeforeInstantiation(beanName, mbdToUse); 生成代理對象,為null就繼續執行 doCreateBean建立對象;
- doCreateBean AnnotationAwareAspectJAutoProxyCreator注冊流程一緻。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
// 省略部分代碼 ....
// 給BeanPostProcessors一個傳回代理而不是目标bean執行個體的機會
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
// 實際建立指定的bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
// AnnotationAwareAspectJAutoProxyCreator在所有bean建立之前會有一個攔截,InstantiationAwareBeanPostProcessor 實作會調用
// postProcessBeforeInstantiation() postProcessAfterInitialization()
// 【createBean:resolveBeforeInstantiation() 實作接口 InstantiationAwareBeanPostProcessor調用,bean執行個體化(doCreateBean)之前執行】
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
3.2 AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】作用;
- bean執行個體化之前,調用AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation();
// 判斷目前bean是否在advisedBeans中。
// isInfrastructureClass 判斷目前bean是否是基礎類型的Advice、Pointcut、Advisor、AopInfrastructureBean、或者是否是切面(@Aspect);則 this.advisedBeans.put(cacheKey, Boolean.FALSE);傳回NULL;
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 判斷目前bean是否是基礎類型的Advice、Pointcut、Advisor、AopInfrastructureBean、或者是否是切面(@Aspect),是則傳回 NULL
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 如果我們有自定義的TargetSource,請在此處建立代理。
// 禁止目标Bean的不必要的預設執行個體化:
// TargetSource将以自定義方式處理目标執行個體。
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
- bean初始化之後,調用 AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization,目标類傳回代理對象;
- getAdvicesAndAdvisorsForBean --> findEligibleAdvisors --> findAdvisorsThatCanApply 查詢符合目标類的AOP攔截器,并對增強器排序;
- specificInterceptors != DO_NOT_PROXY,建立代理對象;
- 将對應攔截器包裝成 Advisor,儲存進 proxyFactory;
- 給容器中傳回目前元件使用cglib增強了的代理對象;
- 以後容器中擷取到的就是這個元件的代理對象,執行目标方法的時候,代理對象就會執行通知方法的流程;
// 如果Bean被子類辨別為要代理的bean,則使用配置的攔截器建立代理 AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
// 包裝Bean的代理,或按原樣包裝Raw Bean執行個體
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;
}
// 判斷目前bean是否是基礎類型的Advice、Pointcut、Advisor、AopInfrastructureBean、或者是否是切面(@Aspect),是則傳回 NULL
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 擷取目前bean的所有增強器(通知方法) Object[] specificInterceptors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
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;
}
// getAdvicesAndAdvisorsForBean --> findEligibleAdvisors --> findAdvisorsThatCanApply 查詢符合目标類的AOP攔截器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
// eligibleAdvisors 可用增強器集合,
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
// 建立AOP代理對象
protected Object createProxy(Class<?> beanClass, String beanName, 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()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将對應攔截器包裝成Advisor,儲存進proxyFactory;
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
// DefaultAopProxyFactory.createAopProxy() 使用cglib或者是jdk代理
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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
2.3 AOP代理類目标方法執行;
AOP 代理對象資訊(比如增強器,目标對象,xxx;

- org.springframework.aop.framework.CglibAopProxy.intercept();攔截目标方法的執行;
-
根據ProxyFactory對象擷取将要執行的目标方法攔截器鍊;
List
-
如果沒有攔截器鍊,直接執行目标方法;
攔截器鍊(每一個通知方法又被包裝為方法攔截器,利用MethodInterceptor機制)
-
如果有攔截器鍊,把需要執行的目标對象,目标方法,
攔截器鍊等資訊傳入建立一個 CglibMethodInvocation 對象,
并調用 Object retVal = mi.proceed();
- 攔截器鍊的觸發過程;
- 如果沒有攔截器執行執行目标方法,或者攔截器的索引和攔截器數組-1大小一樣(指定到了最後一個攔截器)執行目标方法;
-
鍊式擷取每一個攔截器,攔截器執行invoke方法,每一個攔截器等待下一個攔截器執行完成傳回以後再來執行;
攔截器鍊的機制,保證通知方法與目标方法的執行順序;
3 總結
- @EnableAspectJAutoProxy 開啟AOP功能
- @EnableAspectJAutoProxy 會給容器中注冊一個元件 AnnotationAwareAspectJAutoProxyCreator
- AnnotationAwareAspectJAutoProxyCreator是一個後置處理器;
容器的建立流程:
4.1. registerBeanPostProcessors()注冊後置處理器;建立AnnotationAwareAspectJAutoProxyCreator對象
4.2. finishBeanFactoryInitialization()初始化剩下的單執行個體bean
4.2.1. 建立業務邏輯元件和切面元件
4.2.2. AnnotationAwareAspectJAutoProxyCreator攔截元件的建立過程
4.2.3. 元件建立完之後,判斷元件是否需要增強
是:切面的通知方法,包裝成增強器(Advisor);給業務邏輯元件建立一個代理對象(cglib);
執行目标方法:
5.1 代理對象執行目标方法
5.2 CglibAopProxy.intercept();
5.2.1 得到目标方法的攔截器鍊(增強器包裝成攔截器MethodInterceptor)
5.2.2 利用攔截器的鍊式機制,依次進入每一個攔截器進行執行;
5.2.3 效果:
正常執行:前置通知-》目标方法-》後置通知-》傳回通知
出現異常:前置通知-》目标方法-》後置通知-》異常通知