Spring之【初识AOP】
目录
先简单使用下AOP功能体验一下效果
自定义注解
定义一个切面类
业务类
开启AOP功能
测试一下效果
@EnableAspectJAutoProxy注解
思考!
将@EnableAspectJAutoProxy注解去掉
自定义实现BeanDefinitionRegistryPostProcessor
测试效果
AnnotationAwareAspectJAutoProxyCreator
先简单使用下AOP功能体验一下效果
自定义注解
package spring.aop;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 该注解只能用在方法上*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}
定义一个切面类
package spring.aop;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;/*** 切面*/
@Aspect
@Component
public class LogAspect {/*** 切入点表达式* 增强有@Log注解的方法*/@Pointcut("@annotation(spring.aop.Log)")public void pointCut() {}/*** 定义前置增强逻辑*/@Before("pointCut()")public void before() {System.out.println("Log...before...");}/*** 定义后置增强逻辑*/@After("pointCut()")public void after() {System.out.println("Log...after...");}
}
业务类
package spring.aop;import org.springframework.stereotype.Service;@Service
public class AccountService {/*** 需要被增强的方法*/@Logpublic void register() {System.out.println("AccountService#register...");}
}
开启AOP功能
package spring.aop;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** 开启AOP功能*/
@EnableAspectJAutoProxy
@ComponentScan("spring.aop")
public class SpringConfig {
}
测试一下效果
package spring.aop;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class AopMain {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);AccountService accountService = applicationContext.getBean(AccountService.class);accountService.register();}
}
@EnableAspectJAutoProxy注解
- Spring容器启动
- 容器启动过程中会执行BeanDefinitionRegistryPostProcessor的方法回调【invokeBeanFactoryPostProcessor(beanFactory)】
- ConfigurationClassPostProcessor是BeanDefinitionRegistryPostProcessor的实现类,因此会执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
- ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法逻辑中会解析到组件类上的@EnableAspectJAutoProxy注解上的@Import(AspectJAutoProxyRegistrar.class)【processImports方法】
- AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,通过ParserStrategyUtils的instantiateClass方法将其实例化并放入importBeanDefinitionRegistrars集合中
- 最后通过loadBeanDefinitionsFromRegistrars方法对importBeanDefinitionRegistrars集合进行遍历,分别调用它们的registerBeanDefinitions方法
- AspectJAutoProxyRegistrar的registerBeanDefinitions方法中的主要逻辑是将AnnotationAwareAspectJAutoProxyCreator对应的RootBeanDefinition放入容器的beanDefinitionMaps集合中
思考!
通过上面的介绍可知,将AnnotationAwareAspectJAutoProxyCreator对应的BeanDefinition对象放入容器中,后续的AOP功能就会生效
疑问:那如果我不使用@EnableAspectJAutoProxy,而是随便采用一种方式将AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对象放入容器中,如自定义BeanDefinitionRegistryPostProcessor来做到这一点的话,AOP功能是不是同样会生效?现在就来验证一下
将@EnableAspectJAutoProxy注解去掉
package spring.aop;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** 这里注释掉开启AOP功能的注解*/
//@EnableAspectJAutoProxy
@ComponentScan("spring.aop")
public class SpringConfig {
}
自定义实现BeanDefinitionRegistryPostProcessor
package spring.aop;import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;/*** 自定义BeanDefinitionRegistryPostProcessor实现其postProcessBeanDefinitionRegistry方法*/
@Component
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {// 将AnnotationAwareAspectJAutoProxyCreator的BeanDefinition对象放入容器中RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();rootBeanDefinition.setBeanClass(AnnotationAwareAspectJAutoProxyCreator.class);registry.registerBeanDefinition("aop", rootBeanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}
测试效果
AOP功能生效
AnnotationAwareAspectJAutoProxyCreator
看一下AnnotationAwareAspectJAutoProxyCreator的继承体系图,即它是一个Bean后置处理器