详解在Spring中如何使用AspectJ来实现AOP

时间:2022-03-08 09:45:40

aspectj 是通过注解来描述切点与增强的。

1 开发环境要求

因为要使用注解,所以请确保使用的 java5.0 及以上版本。

引入 aspectj 相关类库:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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//标识切面

?
1
2
3
4
5
6
7
8
9
public class prerentaspect {
 /**
  * 增强逻辑
  */
 @before("execution(* rent(..))")//定义切点与增强类型
 public void beforerent() {
  system.out.println("开始执行租赁动作");
 }
}

这个切面只是一个普通的 pojo,只不过加了 @aspect 注解。

@before("execution(* rent(..))") 中的 @before 表示增强类型是前置增强,它的内容是 @aspectj 切点表达式,这里表示的是在目标类的 rent() 方法上织入增强, rent() 可以包含任意入参和任意的返回值。

带  @aspect 的类,通过注解与代码,将切点、增强类型和增强的横切逻辑整合到了一起,是不是很方便呀o(∩_∩)o哈哈~

单元测试:

?
1
2
3
4
5
6
7
8
9
10
11
12
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 配置方式

?
1
2
3
4
5
6
7
8
9
<!-- 目标类-->
<bean id="user" class="net.deniro.spring4.aspectj.user"/>
 
<!-- 切面类-->
<bean class="net.deniro.spring4.aspectj.prerentaspect"/>
 
<!-- 自动创建代理-->
<bean
  class="org.springframework.aop.aspectj.annotation.annotationawareaspectjautoproxycreator"/>

单元测试:

?
1
2
3
4
5
applicationcontext context = new classpathxmlapplicationcontext(spring.xml");
user user = (user) context.getbean("user");
string userid = "001";
user.rent(userid);
user.back(userid);

输出结果与编程方式完全相同。

也可以基于 schema 的 aop 命名空间进行配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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 来配置切点与增强,因为这样更简洁、也更直接。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.jianshu.com/p/abf28c0a15b0