文章目录
前言
在Spring中,如果不在配置类中添加@EnableAspectJAutoProxy,那么所有切面注解是不生效的(springboot因为有自动配置,所以不需要开发人员手工配置@EnableAspectJAutoProxy)
例子
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class AppConfig {
}
@Aspect
@Component
public class LogAspects {
@Pointcut("within(tzb.aop..*)")
public void pointCut() {
}
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(joinPoint.getSignature().getName()+" 运行。。。@Before "+ Arrays.asList(args));
}
}
源码解读
下面,我们就来看下@EnableAspectJAutoProxy这个注解,究竟做了什么
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
看import里的代码
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
// 如果proxyTargetClass为true,则强制指定AutoProxyCreator使用CGLIB进行代理
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// exposeProxy属性
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
一路深入追踪AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);这个代码,来到org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired方法
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
// 省略。。。
// 注册InfrastructureAdvisorAutoProxyCreator(它继承了BeanPostProcessor)
// 将class注册到容器中,order的执行顺序调整为最优
// 在aop中,这里会注册AnnotationAwareAspectJAutoProxyCreator.class这个类到容器
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.class这个类注册到容器。
AnnotationAwareAspectJAutoProxyCreator
那AnnotationAwareAspectJAutoProxyCreator.class这个类又是干嘛用的呢?
它的继承关系,如下图
BeanPostProcessor:后置处理器,即在bean初始化完成前后做些事情
BeanFactoryAware:自动注入BeanFactory
故事,还是要从我们所熟悉的refresh()方法开始说起,上下文的获取,必然会调用此方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 省略代码...
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 省略代码...
}
}
在refresh()方法中,我们重点来看以下2个方法。
invokeBeanFactoryPostProcessors(beanFactory)
// Invoke factory processors registered as beans in the context.
// 把factory processors先注册进context
invokeBeanFactoryPostProcessors(beanFactory);
这个方法里,会调用到如下方法
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
经过org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 省略代码
this.reader.loadBeanDefinitions(configClasses);
// ...
}
当beanName为appConfig时,会走到如下代码
接着到这里,以下这个代码,就是我们在文章开头看到的代码了。
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
// 如果proxyTargetClass为true,则强制指定AutoProxyCreator使用CGLIB进行代理
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// exposeProxy特性
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
继续跟踪
这里,
- 会把AnnotationAwareAspectJAutoProxyCreator这个类注册为BeanDefinition,beanName为org.springframework.aop.config.internalAutoProxyCreator
- 添加了order属性
这里也是我们在文章开头见到的代码,原来AnnotationAwareAspectJAutoProxyCreator就是这样注册到容器的。
至此
我们回到refresh(),来看下效果,如下图
果然org.springframework.aop.config.internalAutoProxyCreator已经放到了beanFactory中。
invokeBeanFactoryPostProcessors(beanFactory)方法这样就执行完了。
internalAutoProxyCreator加入容器了,但是它还并没有被实例化和初始化。
我们接着往下看。
registerBeanPostProcessors(beanFactory)
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 省略代码...
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 省略代码...
}
在上面的代码中,我们知道internalAutoProxyCreator是加入Order属性的,所以在registerBeanPostProcessors(beanFactory)方法中,会走到如上代码。
如上代码,会调用beanFactory.getBean(ppName, BeanPostProcessor.class);
一路追踪,进入doCreateBean()方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 省略代码...
// 执行bean初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 省略代码...
}
经过initializeBean()方法。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 生命周期 step7 BeanNameAware 、BeanClassLoaderAware 、BeanFactoryAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// 省略代码。。。
}
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
这里创建了ReflectiveAspectJAdvisorFactory 和 BeanFactoryAspectJAdvisorsBuilderAdapter 2个类。
至此,AnnotationAwareAspectJAutoProxyCreator的注册就已经完成了,虽然期间代码很长很多,但是只要理清脉络,还是还是很清楚的。
至此,以下beanFactory.getBean(ppName, BeanPostProcessor.class);这段代码算是执行完了。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 省略代码...
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 省略代码...
}
registerBeanPostProcessors(beanFactory);方法也就执行完了(这个方法里剩余的部分没什么可看的)。