本文基于Spring5注解版进行分析
分两大块分析,
- Spring创建AOP切面代理对象流程
- AOP切面方法通知执行流程
Spring的AOP切面功能大家都用过,但是也会有一些人对AOP不是很理解,本文着重解析AOP的工作原理。
AOP是什么?
- 对我们的业务方法实现增强,对执行方法进行拦截。
- 实际就是利用JDK/CGLIB实现动态代理。
AOP应用场景,能帮我们干什么?
- 控制层请求日志打印 ,保存。
- 控制层权限控制。
- 业务层分布式锁。
- Spring 事务。
开始分析:
要用Spring AOP的切面功能,需要启用它,@EnableAspectJAutoProxy
相信大部分人用SpringBoot没有用过此注解,那是因为AspectJ的SpringBoot依赖帮我们自动注入了。
主要是向容器中注册了一个 AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator类图
Aware接口作用:从Spring上下文中获取实例数据的
- BeanFactoryAware:拿到BeanFactory实例,IOC容器。
- BeanClassLoaderAware:拿到当前应用类加载器。
BeanPostProcessor接口的作用:后置处理器
- SmartInstantiationAwareBeanPostProcessor:预测Bean的类型,构造函数。
- InstantiationAwareBeanPostProcessor:可以在容器创建对象前先创建对象。
- BeanPostProcessor:可对实例化Bean做修改,比如给实例化对象属性重新复制,或创建代理
先演示一下:这里我定义一个拦截 service包下及其子包下的类的所有方法。
@Pointcut()的表达式这里不过多说,具体可以百度。
package com.liuqi.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class ServiceAop {
@Pointcut("execution (* com.liuqi.service..*.*(..))")
public void serviceAop() {}
@Before(value = "serviceAop()")
public void doBefore() {
System.out.println("方法执行前通知");
}
@After(value = "serviceAop()")
public void doAfter() {
System.out.println("方法执行后通知");
}
@AfterReturning(value = "serviceAop()", returning = "result")
public void doAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("方法执行后的返回通知");
}
@AfterThrowing(value = "serviceAop()", throwing = "t")
public void doAfterThrowing(JoinPoint joinPoint, Throwable t) {
System.out.println("方法执行异常通知");
}
@Around(value = "serviceAop()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知");
Object proceed = joinPoint.proceed(); // 继续执行通知方法
// 此返回结果,将影响我们实际执行的目标方法的方法结果
return proceed;
}
}
此service类只有一个方法
package com.liuqi.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void add() {
System.out.println("add");
}
}
效果截图:
开始进入正文
首先我们要知道,AOP创建代理对象是在BeanPostProcessor后置处理器的后置通知方法中进行工作的
先找到注册到容器类AnnotationAwareAspectJAutoProxyCreator中的实现方法postProcessAfterInitialization()
在父类AbstractAutoProxyCreator 中有该方法。核心方法wrapIfNecessary()
public class AbstractAutoProxyCreator {
/**
* 如果bean是,使用配置的拦截器创建一个代理被子类识别为要代理的。
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
/**
* this.earlyProxyReferences 创建代理对象时的缓存
*/
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
}
1.0.0:wrapIfNecessary(bean, beanName, cacheKey);
是否需要创建代理对象。
public class AbstractAutoProxyCreator {
/**
* 如有必要,包装给定的bean,即它是否有资格被代理
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return 包装bean或原始bean实例的代理
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
/**
* 如果标记的BeanName不需要创建代理
*/
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
/**
* 如果标记的BeanName不需要创建代理 标记 false,
* 预防创建多实例时下来的重复判断
*/
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/**
* 拿到适配此Bean实例的所有方法拦截器链 --> 通知方法
* @Before, @After, @AfterReturning, @AfterThrowing, @Around
* 且是一个排好序的,因为是(责任链模式执行的) --> 递归执行 后续会讲
*/
// 1.0.1:重点分析
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 标记此BeanName需要创建代理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
/**
* 2.0.0:重点分析
* 创建代理对象
*/
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.0.1:getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
获取拦截器链 (通知方法链,所有可以适配当前Bean实例的通知方法),是一个排好顺序的数组。
public class AbstractAdvisorAutoProxyCreator {
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
/**
* 1.0.2:重点分析
* 查找所有适配的通知方法
*/
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
}
1.0.2:findEligibleAdvisors(beanClass, beanName);
查找所有适配的通知方法
public class AbstractAdvisorAutoProxyCreator {
/**
* 查找所有适配此Bean的通知方法
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
/**
* 1.0.3:重点分析
* 查找出所有的通知方法
*/
List<Advisor> candidateAdvisors = findCandidateAdvisors();
/**
* 检查是否能够应用在此 Bean 实例上拦截
*/
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
/**
* 将通知方法排序 默认的一个 -> AfterThrowing -> AfterReturning -> After -> Around -> Before
* 执行会递归从后往前执行
*/
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
}
1.0.3:findCandidateAdvisors();
查找出所有的通知方法
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Override
protected List<Advisor> findCandidateAdvisors() {
// 添加所有根据超类规则找到的Spring通知方法。
List<Advisor> advisors = super.findCandidateAdvisors();
/**
* 重点记住 this.aspectJAdvisorsBuilder 在什么时候初始化的 后面分析
*
* 从bean工厂中的所有AspectJ切面类,构建通知方法。
*/
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
}
重点记住 this.aspectJAdvisorsBuilder 在什么时候初始化的 后面分析。
它保存了我们所有的切面类,和通知方法。
2.0.0:createProxy() 创建代理对象,非常重要
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* 创建代理对象
* @param beanClass bean 类型
* @param beanName bean name
* @param specificInterceptors
* @param targetSource 代理目标对象 --> Bean 实例
* @return
*/
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);
/**
* 如果 @EnableAspectJAutoProxy(proxyTargetClass = false) 默认就是 false
*/
if (!proxyFactory.isProxyTargetClass()) {
/**
* 设置是否直接代理目标类,而不仅仅是代理特定接口。默认为 fasle
*/
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);
}
/**
* 2.0.1:重点分析
* 开始创建代理
*/
return proxyFactory.getProxy(getProxyClassLoader());
}
}
2.0.1:proxyFactory.getProxy(getProxyClassLoader());
创建代理对象
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
/**
2.0.2重点分析
* createAopProxy() 创建AOP使用的代理器 JDK或CGLIB
* getProxy()创建代理对象
*/
return createAopProxy().getProxy(classLoader);
}
}
2.0.2:createAopProxy()
创建AOP的代理器,JDK或者CGLIB
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/**
* @EnableAspectJAutoProxy(proxyTargetClass = true)
* config.isProxyTargetClass() 是否开启强制使用CGLIB代理
*/
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
/**
* 如果目标对象是个接口 || 当且仅当指定的类是动态的时
*/
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config); // JDK动态代理
}
return new ObjenesisCglibAopProxy(config); // CGLIB 动态代理
}
else {
return new JdkDynamicAopProxy(config); // JDK动态代理
}
}
/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
}
2.0.3:getProxy()
就是JDK或者CGILB创建代理对象了。
- CGLIB代理回调:CglibAopProxy类下的类部类DynamicAdvisedInterceptor
- JDK代理回调:JdkDynamicAopProxy
到此AOP切面创建代理对象就结束了。
回归到前面提到的this.aspectJAdvisorsBuilder保存了我们所有的切面类,和通知方法。它在什么时候进初始化的.
核心属性
public class BeanFactoryAspectJAdvisorsBuilder {
/**
* 当前Spring Bean工厂
*/
private final ListableBeanFactory beanFactory;
private final AspectJAdvisorFactory advisorFactory;
/**
* @Aspect 标注的类名集合
*/
@Nullable
private volatile List<String> aspectBeanNames;
/**
* key @Aspect 标注的类名集合
* value @Aspect 下的所有通知方法
*/
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();
}
参考1.0.3的findCandidateAdvisors();查找所有的切面通知方法。
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()构建。
解释:
会在第一次获取所有通知方法的时候,从容器中拿到所有的Bean name,然后通过BeanName获取Bean的定义信息,在通过反射获取类上是否有@Aspect注解。如果有,反射获取该类中所有有通知方法注解的方法。然后再缓存起来,下次再获取直接走缓存。
public class BeanFactoryAspectJAdvisorsBuilder {
/**
* @Aspect 标注的类名集合
*/
@Nullable
private volatile List<String> aspectBeanNames;
/**
* key @Aspect 标注的类名集合
* value @Aspect 下的所有通知方法
*/
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
/**
* 第一次进行会等于 null
*/
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
// 双重检验锁
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 从容器中拿到所有的 Bean name
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
// 检查Bean name是否合格
if (!isEligibleBean(beanName)) {
continue;
}
// 拿到Bean的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 是否切面类 ( 是否有 @Aspect 注解)
if (this.advisorFactory.isAspect(beanType)) {
// 省略大段代码...
// this.aspectBeanNames添加切面类, this.advisorsCache添加通知方法
}
else {
//省略打断代码...
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
/**
* 如果已经有缓存了
*/
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
}
开始讲解AOP切面执行流程
流程图,必需了解到各个通知拦截执行顺序。由于递归这种文字描述不太清楚,后面直接看代码
JDK代理的方法执行器是: ReflectiveMethodInvocation.proceed() CGLIB代理的方法执行器是: CglibMethodInvocation.proceed(),但是 CglibMethodInvocation继承了 ReflectiveMethodInvocation,所以我直接分析 ReflectiveMethodInvocation
ReflectiveMethodInvocation 通知方法执行开始
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Override
@Nullable
public Object proceed() throws Throwable {
/**
* 从-1的索引开始,并提前递增。
*/
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
/**
* 如果当前 index 自增, 等于拦截方法数组索引
* 执行目标方法
*/
return invokeJoinpoint();
}
// 获取当前 自增后的索引 第一次也就是 索引0
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
/**
* 省略部分代码...
*/
}
else {
/**
* 开始执行拦截方法 例如 @AfterThrowing, @AfterReturning, @After, @Around, @Before
*
* 注意:拦截方法里面会有一个默认的 它并没有做什么工作
*/
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
这行代码是关键,执行通知方法处理器,注意:这里入参把 this 传进去了
1.0.0:第一步是执行默认的通知方法。
return mi.proceed();,mi是方法入参,查看之前的 invoke(this); mi 就是ReflectiveMethodInvocation实例,它又回调了proceed()方法。
public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable {
private static final ThreadLocal<MethodInvocation> invocation =
new NamedThreadLocal<>("Current AOP method invocation");
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
/**
* 设置当前线程的通知方法拦截器
*/
invocation.set(mi);
try {
/**
* 这里它又回调了 proceed() 方法
*/
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
}
2.0.0:@AfterThrowing异常通知方法执行器
在1.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
它进行捕获了异常,如果回调去执行其他通知方法,发生异常,则执行异常通知方法。
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
/**
* 回调 proceed()
*/
return mi.proceed();
}
catch (Throwable ex) {
/**
* 如果发生异常,就执行异常通知方法
*/
if (shouldInvokeOnThrowing(ex)) {
// 执行异常通知方法 这些是入参
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
}
3.0.0:@AfterReturning返回通知方法执行器
在2.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
他在回调proceed()拿到返回值后,执行返回通知方法执行器
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
/**
* 回调去执行通知方法,并拿到结果的返回值
*/
Object retVal = mi.proceed();
/**
* 执行 返回通知方法
*/
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
4.0.0:@After目标方法执行后通知方法执行器
在3.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
回调proceed(), 它有一个finally 处理,所以无论执行结果是什么,都会执行后置通知方法。
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
/**
* 回调执行 proceed()
*/
return mi.proceed();
}
finally {
/**
* 无论执行结果正常还是异常,都会执行 后置通知方法
*/
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
}
4.0.0:@Around环绕通知方法执行器
在4.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
会直接执行环绕通知方法,并拿到返回值,结束递归。
注意:我们在环绕通知中执行的 proceedingJoinPoint.proceed() 等同于之前的 mi.proceed()。如果不去调用proceedingJoinPoint.proceed() 就不会执行前置通知方法。
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
/**
* 获取环绕通知的 {@link ProceedingJoinPoint} 切入点连接器实例
*/
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
/**
* 执行环绕通知方法
* 如果在环绕通知方法中运行了 ProceedingJoinPoint.proceed();
* 等同于之前的回调 mi.proceed()
*/
return invokeAdviceMethod(pjp, jpm, null, null);
}
}
5.0.0:@Before目标方法执行前通知方法执行器
在4.0.0环绕通知方法中运行了 proceedingJoinPoint.proceed(),就是这个通知方法。
会先执行前置通知方法,在回调。
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
/**
* 先执行 目标方法执行前通知
*/
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
/**
* 回调 proceed()
*/
return mi.proceed();
}
}
6.0.0:又来到了ReflectiveMethodInvocation.proceed()
因为前置通知方法是数组最后一个,所以会直接去执行目标方法,拿到返回结果,再结束递归,一层一层往上返回。
@Before -> @Around -> @After -> @AfterReturning -> @AfterThrowing
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
/**
* 当数组长度减一后,等于当前索引
* 执行目标方法
* 拿到返回值,将结束递归执行 依次往上返回结果
*/
return invokeJoinpoint();
}
/**
* 省略很多代码...
*/
}
}
AOP的分析到此结束,个人觉得分析得不是很好,请勿喷☺
感兴趣的朋友,可以自己断点去追踪下源码,一步一步看AOP的执行流程,效果会更好。然后照着AOP的通知方法执行流程,自己也手写一个,那肯定是非常棒的。
值得一提:
- Spring的声明式事务@Transactional也是AOP去实现的。
- 异步处理@Async也是AOP实现的。
- AOP代理对象都是通过BeanPostProcessor后置处理器去创建的。
- AOP在Spring中应用非常多。
下面我分享下,如何自己动手找到Spring AOP在什么时候帮我们创建代理对象的。
先下一个断点在finishBeanFactoryInitialization(beanFactory);
实例化所有剩下的单实例Bean
再下一步到beanFactory.preInstantiateSingletons();这:实例化所有的单实例Bean
在循环体里面下一个断点,一直按F9跳过,直到看到我们要创建AOP切面的BeanName
在getBean(BeanName)处下一个断点,因为不管是FactoryBean创建Bean还是注解创建Bean都是执行getBean(BeanName)。
一直下一步,会执行到 doGetBean,先从已经创建的Bean缓存中查询,一开始肯定没有的。
再断点往下走,会来到一个匿名内部类中,createBean(beanName), 创建Bean,这里就开始创建Bean了。
继续断点往下走,会来到 doCreateBean(beanName) 正式的创建Bean实例。
断点继续往下走,开始帮我们创建实例了。此时已经创建了实例,但类型是我们的原始类型。
再往下执行到这一行 exposedObject = initializeBean(beanName, exposedObject, mbd);,
populateBean(beanName, mbd, instanceWrapper);是为Bean实例的属性赋值的,所以不会创建代理对象的。
直接下一步操作,唉,Bean实例对象已经变成了CGLIB代理对象了。说明创建代理对象在initializeBean(beanName, exposedObject, mbd);方法里面完成的。
再来一次断点,进入到 initializeBean(beanName, exposedObject, mbd); 方法中。
invokeAwareMethods如果你的Bean实现了一些Aware接口,就回调执行。
再下一步:applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
应用所有的BeanPostProcessor后置处理器的前置通知方法。
可以看出。执行到这里之前,Bean实例还是原始类型。
再下一步走到:invokeInitMethods(beanName, wrappedBean, mbd);执行所以有的初始化方法。
走到这一步的时候,Bean实例还是原始类型。
再往下走来到:applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 这也是initializeBean(beanName, exposedObject, mbd); 最后一步了。
应用所有的BeanPostProcessor后置处理器的后置通知方法。
在执行此方法之前,Bean实例依然还是原始类型。
再往下走一步:就变成了 CGLIB代理对象了,说明创建代理对象是在BeanPostProcessor后置处理器的后置通知方法中完成的。
AOP创建代理对象的后置处理器AnnotationAwareAspectJAutoProxyCreator。
再使用@EnableAspectJAutoProxy注解的时候,向容器中导入了这类。
觉得对您有帮助,就点个赞呗。😀