说说在 Spring 中如何使用 AspectJ 来实现 AOP
程序员文章站
2022-03-03 12:37:00
...
AspectJ 是通过注解来描述切点与增强的。
1 开发环境要求
- 因为要使用注解,所以请确保使用的 Java5.0 及以上版本。
- 引入 AspectJ 相关类库:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>${aopalliance.version}</version>
</dependency>
2 编程方式
@Aspect//标识切面
public class PreRentAspect {
/**
* 增强逻辑
*/
@Before("execution(* rent(..))")//定义切点与增强类型
public void beforeRent() {
System.out.println("开始执行租赁动作");
}
}
这个切面只是一个普通的 POJO,只不过加了 @Aspect 注解。
@Before("execution(* rent(..))")
中的 @Before
表示增强类型是前置增强,它的内容是 @AspectJ
切点表达式,这里表示的是在目标类的 rent() 方法上织入增强, rent() 可以包含任意入参和任意的返回值。
带 @Aspect
的类,通过注解与代码,将切点、增强类型和增强的横切逻辑整合到了一起,是不是很方便呀O(∩_∩)O哈哈~
单元测试:
AspectJProxyFactory factory = new AspectJProxyFactory();
//设置目标类
factory.setTarget(new User());
//添加切面类
factory.addAspect(PreRentAspect.class);
User proxy = factory.getProxy();
String userId = "001";
proxy.rent(userId);
proxy.back(userId);
输出结果:
--开始执行租赁动作--
User:租赁【充电宝】
User:归还【充电宝】
3 配置方式
<!-- 目标类-->
<bean id="user" class="net.deniro.spring4.aspectj.User"/>
<!-- 切面类-->
<bean class="net.deniro.spring4.aspectj.PreRentAspect"/>
<!-- 自动创建代理-->
<bean
class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>
单元测试:
ApplicationContext context = new ClassPathXmlApplicationContext(spring.xml");
User user = (User) context.getBean("user");
String userId = "001";
user.rent(userId);
user.back(userId);
输出结果与编程方式完全相同。
也可以基于 Schema 的 aop 命名空间进行配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--aspectj 驱动器 -->
<aop:aspectj-autoproxy/>
<!-- 目标类-->
<bean id="user" class="net.deniro.spring4.aspectj.User"/>
<!-- 切面类-->
<bean class="net.deniro.spring4.aspectj.PreRentAspect"/>
</beans>
这样的配置更加简洁。其实在 <aop:aspectj-atuoproxy/>
内部已经采用了自动代理模式啦 O(∩_∩)O哈哈~
<aop:aspectj-atuoproxy/>
的 proxy-target-class
属性,默认为 false ,表示使用 JDK 动态代理技术织入增强;此值为 true 则表示使用 CGLib 动态代理技术织入增强 。 如果目标类没有声明接口,那么即使 proxy-target-class
设置为 false,也会自动使用 CGLib 动态代理织入增强的哟O(∩_∩)O哈哈~
基于 Java5.0+ 的项目,建议使用 AspectJ 来配置切点与增强,因为这样更简洁、也更直接。