1.@EnableAspectJAutoProxy
我们从@EnableAspectJAutoProxy这个注解开始说起,因为我们都知道想要开启基于注解的AOP的自动代理就需要加上这个注解。
进入这个注解,它通过@Import标签向容器当中导入了一个注册器。AspectJAutoProxyRegistrar
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Import(AspectJAutoProxyRegistrar.class)
该类的源码如下:
- class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
-
- /**
- * Register, escalate, and configure the AspectJ auto proxy creator based on the value
- * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
- * {@code @Configuration} class.
- */
- @Override
- public void registerBeanDefinitions(
- AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
-
- AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
-
- AnnotationAttributes enableAspectJAutoProxy =
- AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
- if (enableAspectJAutoProxy != null) {
- if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
- AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
- }
- if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
- AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
- }
- }
- }
-
- }
实现了ImportBeanDefinitionRegistrar接口以及其中的唯一一个方法:registerBeanDefinitions
重点看这行代码:
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
该方法跟进去最底层其实就是注册一个BeanDefinition,源码如下:
- private static BeanDefinition registerOrEscalateApcAsRequired(
- Class<?> cls, BeanDefinitionRegistry registry, @Nullable 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;
- }
以上代码就是首先判断容器中是否一个名字为:AUTO_PROXY_CREATOR_BEAN_NAME 的一个BeanDefinition,如果没有就创建对应的bean,并根据AUTO_PROXY_CREATOR_BEAN_NAME作为keyName,Value就是:AnnotationAwareAspectJAutoProxyCreator
2.准备AOP代码材料
我们可以写一段非常简单的AOP代码:
被增强对象以及方法:
- public class MyTarget {
- public void print(){
- System.out.println("print().......");
- }
- }
切面类以及切入的点:
- @Aspect
- public class MyAdvice {
- @Pointcut(value="execution(public void com.itheima.aop.MyTarget.*(..))")
- public void pointcut(){
- }
- @Around(value = "pointcut()")
- public Object testAround(ProceedingJoinPoint point)throws Throwable{
- System.out.println("before......");
- // 这个就是方法的返回值
- Object proceed = point.proceed();
- System.out.println("after....");
- return proceed;
- }
- }
配置自动代理以及加入Spring容器进行管理:
- @EnableAspectJAutoProxy
- @Configuration
- public class MyConfigAop {
- //将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)需要交给spring管理
- @Bean
- public MyTarget myTarget(){
- return new MyTarget();
- }
- @Bean
- public MyAdvice myAdvice(){
- return new MyAdvice();
- }
- }
运行结果:
- before......
- print().......
- after....
Debug查看:

image-20211214181740191
创建的就是AnnotationAwareAspectJAutoProxyCreator
3.继承结构

image-20211214183327446
顶部基类实现了BeanPostProcessor接口和BeanFactoryAware,说明这个类是一个后置处理器,并且初始化的时候,会自动装配BeanFactory。
注意:我们的
AnnotationAwareAspectJAutoProxyCreator是在容器初始化的过程中进行创建,具体调用时机是在registerBeanPostProcessors(beanFactory);方法
4.getBean的执行流程
当我们通过 beanFactory去 getBean() 的时候,调用过程是 getBean---->doGetBean----->getSingleton------->getObject-------->CreatBean------->doCreatBean,我们通过debug也能看到:

在doCreate方法会调用initializeBean初始化bean,代码如下:
- protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
- invokeAwareMethods(beanName, bean);
- return null;
- }, getAccessControlContext());
- }
- else {
- //处理Aware接口的方法回调
- invokeAwareMethods(beanName, bean);
- }
-
- Object wrappedBean = bean;
- if (mbd == null || !mbd.isSynthetic()) {
- //遍历所有后置处理器 调用后置处理器的postProcessBeforeInitialization方法
- wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
- }
-
- try {
- //执行自定义初始化方法如自定义的:init方法
- 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()) {
- //遍历所有后置处理器 调用postProcessAfterInitialization
- wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
- }
-
- return wrappedBean;
- }
这也验证了后置处理器是在创建完成 初始化前后起作用的
而从AnnotationAwareAspectJAutoProxyCreator继承结构中也可以到看到,它是间接继承了后置处理器BeanPostProcessor接口,其中的方法就是以下两个:
- public interface BeanPostProcessor {
- //bean实例化前的回调操作
- @Nullable
- default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
- //bean实例化后的回调操作
- @Nullable
- default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
-
- }
也就是说该类会在bean的实例化和初始化的前后起作用
那我们的代码对象是在哪儿创建的呢?我们Debug一路追踪发现,其实是在bean初始化完成后调用 postProcessAfterInitialization方法中完成代理对象的创建
- public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
- if (bean != null) {
- Object cacheKey = getCacheKey(bean.getClass(), beanName);
- if (this.earlyProxyReferences.remove(cacheKey) != bean) {
- return wrapIfNecessary(bean, beanName, cacheKey);
- }
- }
- return bean;
- }
- 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;
- }
- if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
- this.advisedBeans.put(cacheKey, Boolean.FALSE);
- return bean;
- }
-
- // Create proxy if we have advice.
- 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;
- }
真正的代理对象是在wrapIfNecessary方法中,Debug也能看到:

image-20211214192732274
小结:一下这个包装方法wrapIfNecessary
1)、获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
获取到能在bean使用的增强器。
给增强器排序
2)、保存当前bean在advisedBeans中
3)、如果当前bean需要增强,创建当前bean的代理对象;
获取所有增强器(通知方法)
保存到proxyFactory
创建代理对象:Spring自动决定 JdkDynamicAopProxy(config);jdk动态代理;ObjenesisCglibAopProxy(config);cglib的动态代理;
给容器中返回当前组件使用cglib增强了的代理对象;
至此,我们Spring Refresh启动过程的第六步源码分析完毕:
bean 后处理器,充当 bean 的扩展点,可以工作在 bean 的实例化、依赖注入、初始化阶段
AutowiredAnnotationBeanPostProcessor 功能有:解析 @Autowired,@Value 注解
CommonAnnotationBeanPostProcessor 功能有:解析 @Resource,@PostConstruct,@PreDestroy
AnnotationAwareAspectJAutoProxyCreator 功能有:为符合切点的目标 bean 自动创建代理
主要涉及到以上三个核心处理器的讲解,最后通过一张图进行总结:
