目前最受欢迎的 AOP 库有两个,一个是 AspectJ, 另外一个就是我们今天讲的 Spring AOP。
概念部分在先前的篇幅中介绍:https://blog.csdn.net/youhaiguo/article/details/101781682
本篇主要讲解Spring Aop的简单使用。
使用Spring AOP进行编程的实例:
- 修改pom文件中的支持,加入相关依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>
com.springsource.org.aspectj.weaver
</artifactId>
<version>1.6.8.RELEASE</version>
</dependency>
2.1 用xml配置方法进行aop编程:
a. 声明dao接口和实现类,代码略。但是要在Impl类上面加上@Componet注解,声明此类被spring容器托管
b. 声明service接口和实现类,代码略。但是要在Impl类上加上@Componet注解,声明此类被spring容器托管。同时要在Impl类的dao应用上面加上@Autowired,声明自动注入。
c.新建类TransDemo,声明4个函数前置、后置、环绕、异常抛出。这个类就是我们的代理,代码如下:
public class TransDemo {
public void begin(){
System.out.println("start tansaction");
}
public void end(){
System.out.println("end transaction");
}
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("begin transaction");
joinPoint.proceed();
System.out.println("commit transaction");
}
public void thorwExption() throws Exception {
throw new Exception("制造一个异常");
}
}
d. 创建spring配置文件,如下所示:
<?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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
>
<context:component-scan base-package="com.qf.aopdemo"></context:component-scan>
<bean id="transDemo" class="com.qf.aopdemo.tansaction.TransDemo"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.qf.aopdemo.service.*.*.*(..))" id="p1" />
<aop:aspect ref = "transDemo">
<!--前置通知-->
<aop:before method="begin" pointcut-ref="p1" />
<!--后置通知-->
<aop:after-returning method="end" pointcut-ref="p1"/>
<!--环绕通知-->
<aop:around method="around" pointcut-ref="p1"/>
</aop:aspect>
</aop:config>
</beans>
e.新建测试类,代码如下:
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-aop.xml");
UserService userService = applicationContext.getBean(UserService.class);
UserInfo user = new UserInfo();
user.setAge(19);
user.setName("yangxin");
userService.addUser(user);
userService.deleteUser(user);
}
}
2.2使用注解的方法进行aop编程
a.新建基于注解的切面类,内容如下:
@Aspect
public class TransDemo2 {
//定义切点
@Pointcut(value="execution(* com.qf.aopdemo.*.*.*(..))")
public void point(){
}
@Before(value="point()")
public void before(){
System.out.println("transaction begin before");
}
@AfterReturning(value = "point()")
public void after(){
System.out.println("transaction commit after");
}
@Around("point()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("transaction begin around");
joinPoint.proceed();
System.out.println("transaction commit around");
}
}
b.修改spring-aop.xml,内容如下:
<bean id="transactionDemo2" class = "com.qf.aopdemo.tansaction.TransDemo2"/>
<aop:aspectj-autoproxy />
c.运行测试类,同上。
总结:
Spring Aop的常见注解
a) @Pointcut
b) @Before
c) @AfterReturning
d) @AfterThrowing
e) @After
f) @Around
织入点语法:
a) execution(修饰符 返回类型 方法名(形参列表)):声明这是一个织入点。
b) 参数模式稍微有点复杂:
i. ()匹配了一个不接受任何参数的方法,
ii. (…)匹配了一个接受任意数量参数的方法(零或者更多)
iii. 模式(*)匹配了一个接受一个任何类型的参数的方法
iv. 模式(*,String)匹配了一个接受两个参数的方法,第一个可以是任意类型, 第二个则必须是String类型
织入点语法举例:
a) 任意公共方法的执行:
execution(public * *(…))
b) 任何一个名字以“set”开始的方法的执行:
execution(* set*(…))
c) AccountService接口定义的任意方法的执行:
execution(* com.xyz.service.AccountService.*(…))
d) 在service包中定义的任意方法的执行:
execution(* com.xyz.service..(…))
e) 在service包或其子包中定义的任意方法的执行:
execution(* com.xyz.service….(…))