当前位置: 首页 > news >正文

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后置处理器

http://www.dtcms.com/a/317728.html

相关文章:

  • 应急响应linux
  • 英伟达算力卡巅峰对决:H100、A100与消费级显卡哪里找?
  • 数语科技登陆华为云商店,助力企业释放数据潜能
  • day20|学习前端
  • JavaScript 基础语法
  • 频数分布表:数据分析的基础工具
  • Adobe Analytics 数据分析平台|全渠道客户行为分析与体验优化
  • Qt 容器类详解:顺序容器与关联容器及其遍历方法
  • [LVGL] 配置lv_conf.h | 条件编译 | 显示屏lv_display
  • 组合模式(Composite Pattern)及其应用场景
  • 基于spring boot的个人博客系统
  • tkwebview-tkinter的web视图
  • 解决云服务器端口无法访问的方法
  • java学习 leetcode24交换链表节点 200岛屿数量 +一些开发任务
  • Redis(七):Redis高并发高可用(主从复制)
  • JP3-4-MyClub后台前端(二)
  • C++、STL面试题总结(三)
  • 考研408_数据结构笔记(第四章 串)
  • 第五十一章:AI模型服务的“百变面孔”:WebUI/CLI/脚本部署全解析
  • 功能安全和网络安全的综合保障流程
  • Transformers简单介绍 - 来源于huggingface
  • 虚幻GAS底层原理解剖五 (AS)
  • 从案例学习cuda编程——线程模型和显存模型
  • git 清理submodule
  • PowerShell部署Windows爬虫自动化方案
  • 【ArcGIS】分区统计中出现Null值且Nodata无法忽略的问题以及shp擦除(erase)的使用——以NDVI去水体为例
  • DevOps时代的知识基座革命:Gitee Wiki如何重构研发协作范式
  • Unity轻量观察相机
  • 利用DeepSeek编写go语言按行排序程序
  • centos配置java环境变量