当前位置: 首页 > 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.xdnf.cn/news/1249129.html

相关文章:

  • Agent安全机制:权限控制与风险防范
  • 海康威视相机,MVS连接成功,但无图像怎么办?
  • 云计算一阶段Ⅱ——12. SELinux 加固 Linux 安全
  • 统计鱼儿分布情况 Java
  • libpq库使用
  • 二叉树算法
  • Mysql常用语句
  • Bilateral Reference for High-Resolution Dichotomous Image Segmentation
  • 智慧社区(八)——社区人脸识别出入管理系统设计与实现
  • 轻量应用服务器Centos系统上安装jdk8和Jdk17教程(详细)
  • (ZipList入门笔记二)为何ZipList可以实现内存压缩,可以详细介绍一下吗
  • 在AI时代,如何制定有效的职业规划?AI时代职业规划+AI产品经理角色
  • 探索设计模式的宝库:Java-Design-Patterns
  • FastDeploy2.0:报qwen2.embed_tokens.weight
  • 3. 为什么 0.1 + 0.2 != 0.3
  • 多传感器融合
  • Redis之Set和SortedSet类型常用命令
  • leetcode-python-删除链表的倒数第 N 个结点
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-邮箱重置密码
  • 使用ProxySql实现MySQL的读写分离
  • ubuntu24安装vulkan-sdk
  • 一文搞定JavaServerPages基础,从0开始写一个登录与人数统计页面
  • Rust进阶-part4-智能指针2
  • 力扣106:从中序与后序遍历序列构造二叉树
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-登录实现
  • Redis里面什么是sdshdr,可以详细介绍一下吗?
  • Linux lvm逻辑卷管理
  • 跑yolov5的train.py时,ImportError: Failed to initialize: Bad git executable.
  • 【Linux】特效爆满的Vim的配置方法 and make/Makefile原理
  • 一种红外遥控RGB灯带控制器-最低价MCU