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 自动创建代理
主要涉及到以上三个核心处理器的讲解,最后通过一张图进行总结: