spring注解-AOP动态代理-@EnableAspectJAutoProxy注解如
何⼯作
⼀.概述
AOP⾯向切⾯编程,⽣成⽬标⽅法所属类的代理类。代理类和⽬标类的关系:代理类继承⽬标类,并重载了⽬标类的⽅法。
代理类重载⽅法体⾥加⼊了切⾯业务逻辑和⽬标类⽅法的调⽤。
⽤户如何使⽤:从容器中获取⽬标类,实际上是获取代理类的实例, 代理类实例调⽤重载了⽗类的⽅法,就实现了AOP。
⼆.步骤
1.在配置类上添加@EnableAspectJAutoProxy注解,开启注解版的AOP功能
2.声明切⾯类:@Aspect表明这是⼀个切⾯类,注:@Aspect是spring-annotation2/libs/aspectj.weaver-
1.6.8.RELEASE.jar的注解,
在其org.aspectj.lang.annotation包下包含了切⾯相关的的注解。aop包下载地址:aspectj
3.声明切⾯⽅法:
1.切点:在哪些⽬标⽅法上添加该切⾯⽅法 。切点表达式:execution(* com.dr.service.*.buy*(..)):⽅法访问权限 包路径.类名.⽅法名(参数类型,参数类型...)
参数类型可以⽤“..”代替。
2.重⽤切点:在切⾯中声明切点⽅法:添加@Pointcut注解, @Pointcut(value="execution(*******)") 切点⽅法返回值 void,⽅法体为空。
在切⾯⽅法上引⽤切点:在通知类型注解⾥指定 pointcut="切⾯类.切点⽅法()"
3.⼏种通知类型:
1.@Before
到此,AOP功能就实现了。。。
三、运⾏流程源码解析
1.spring容器⽤DefaultListableBeanFactory保存 beanNames集合 ,beanName和BeanDefinition映射的集合
默认加载这6个bean定义:
这6个bean定义信息加载时机:
1.开始:
ApplicationContext ctx=new AnnotationConfigApplicationContext(MainConfig.class);
2.进⼊构造⽅法:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
spring aop应用场景register(annotatedClasses);
refresh();
}
3.进⼊this()
public AnnotationConfigApplicationContext() {
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
4.进⼊ader = new AnnotatedBeanDefinitionReader(this);
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
5.再进⼊
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
}
istry);
最终调⽤AnnotationConfigUtils的⽅法:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) 完成注册
AnnotationConfigApplicationContext调⽤⾃⼰的属性AnnotatedBeanDefinitionReader完成注
册,AnnotatedBeanDefinitionReader⼜调
⽤AnnotationConfigUtils完成注册,⽽AnnotationConfigUtils定义了这6个beanName常量。
这6个bean如何注册:
if (!ainsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); }
这6个beanName,spring内部有对应的类: RootBeanDefinition def = new
RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
开始分析AOP原理:
⼀、@EnableAspectJAutoProxy如何开启aop动态代理功能
它的注解源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
@Import(AspectJAutoProxyRegistrar.class)的功能是注册⼀个bean:AspectJAutoProxyRegistrar.class是AspectJ⾃动代理注册器
那么spring什么时候解析配置类上⾯的注解:(也是解析配置类上的注解,加载bean的流程)
1.进⼊AnnotationConfigApplicationContext构造器,运⾏到refresh()
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
......
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
......
}
}
3.进⼊invokeBeanFactoryPostProcessors(beanFactory),
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (TempClassLoader() == null && ainsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new BeanClassLoader()));
}
}
4.PostProcessorRegistrationDelegate类invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()),调⽤beanFactory的后置处理器
invokeBeanFactoryPostProcessors执⾏流程:
1.判断beanFactory是否 BeanDefinitionRegistry类型
如果是:
1.遍历ApplicationContext中的beanFactory后置处理器:
如果beanFactory是BeanDefinitionRegistryPostProcessor类型:
调⽤BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry(registry)
postProcessBeanDefinitionRegistry(registry)作⽤是:Derive further bean definitions from the configuration classes in the registry 从beanFactory中解析出所有要加载的bean
否则就先加到集合中保存。
2.从DefaultListableFactory之前默认加载6个BeanDefinition中到BeanDefinitionRegistryPostProcessor类型并且实现了PriorityOrdered接⼝的bean 定义。
把它实例化:Bean(ppName, BeanDefinitionRegistryPostProcessor.class)),保存到集合中
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.Bean(ppName,
BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
3.invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);遍历第2步得到的BeanDefinitionRegistryPostProcessor集合,调⽤它的
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) 从所有配置类中解析出要加载的bean。
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (ains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (ains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
processConfigBeanDefinitions(registry);
}
第4步解析到这⾥,停⽌,因为现在要了解 EnableAspectJAutoProxy注解什么时候加载AspectJAutoProxyRegistrar
5.进⼊processConfigBeanDefinitions(registry)⽅法。这⾥提醒⼀下:ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor 以下操作是在ConfigurationClassPostProcessor类中
运⾏。
1.从DefaultListableBeanFactory的bean定义集合中出标了@Configuration的bean定义,加到集合中
2.解析所有的配置类:使⽤ConfigurationClassParser类解析所有配置类--->parse(配置类集合)
6.进⼊ConfigurationClassParser.parse(配置类集合)
遍历配置类,对每个配置类的每个注解递归解析到 @Import注解,再加加载该注解指定要加载的类
于是,这时加载了AspectJAutoProxyRegistrar.class,这个类的作⽤是加载AnnotationAwareAspectJAutoProxyCreator.class
---------------------现在分析AspectJAutoProxyRegistrar如何注册AnnotationAwareAspectJAutoProxyCreator-------------------------
1.ConfigurationClassParser解析完配置类后(上个解析第5步),ConfigurationClassPostProcessor类中的ConfigurationClassBeanDefinitionReader调⽤loadBeanDefinitions(ConfigurationClass configClasses集合)
ConfigurationClass包含了对应配置类解析出的所有bean定义
2.ConfigurationClassParser中的⽅法ImportBeanDefinitionRegistrars());这时就加载了AnnotationAwareAspectJAutoProxyCreator
3. AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar ,这时 AspectJAutoProxyRegistrar调⽤registerBeanDefinitions(metadata, istry)
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
}
4.
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (Boolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (Boolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论