Spring 基于Aspectj的注解开发AOP(一)-前置通知@Before
一、Aspectj 常用注解
1、@Before 前置通知,相当于BeforeAdvice
ps:在目标方法之前执行
应用场景:如在保存之前进行权限校验,只有管理员身份才有权限保存;
2、@AfterReturning 后置通知,相当于AfterReturningAdvice
ps:在目标方法之后执行
应用场景:如在删除一条记录时候,记录是谁什么时候删除的;
3、@Around 环绕通知,相当于MethodInterceptor
ps:在目标方法之前和之后执行,可以阻止目标方法执行
应用场景:如事务处理,在目标方法之前开启事务,目标方法之后提交或回滚事务;
4、@AfterThrowing 异常抛出通知,相当于ThrowAdvice
ps:只会在目标方法有异常的情况下,才会执行
5、@After 最终final通知,不管是否有异常,该通知都会执行;
二、在通知中通过value属性定义切点
在通知中通过value属性定义切点
•通过execution函数,可以定义切点的方法切入
•语法:
–execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
•例如
–匹配所有类public方法execution(public * *(..))
–匹配指定包下所有类方法execution(* com.imooc.dao.*(..))
-不包含子包–execution(* com.imooc.dao..*(..)) ..*表示包、子孙包下所有类
–匹配指定类所有方法execution(* com.imooc.service.UserService.*(..))
–匹配实现特定接口所有类方法 execution(* com.imooc.dao.GenericDAO+.*(..))
–匹配所有save开头的方法 execution(* save*(..))
三、可以在方法中传入JoinPoint对象,用来获取切点信息(ps:案例中有介绍)
四、入门案例
applicationContext.xml:
<?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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启Aspectj的注解开发,自动代理==================-->
<aop:aspectj-autoproxy/>
<!--目标类-->
<bean id="ProductDao" class="com.lucifer.aspectj.demo.ProductDao"/>
<!--定义切面-->
<bean id="MyAspectjAnno" class="com.lucifer.aspectj.demo.MyAspectjAnno"/>
</beans>
ProductDao 目前类:
package com.lucifer.aspectj.demo;
/**
* @Author: Lucifer
* @Date: 2019/3/21 00:28
* @Description:
*/
public class ProductDao {
public void save(){
System.out.println("保存商品");
}
public void update(){
System.out.println("修改商品");
}
public void delete(){
System.out.println("删除商品");
}
public void findOne(){
System.out.println("查询一个商品");
}
public void findAll(){
System.out.println("查询所有商品");
}
}
MyAspectjAnno 切面类:
package com.lucifer.aspectj.demo;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @Author: Lucifer
* @Date: 2019/3/21 00:31
* @Description: 切面类
*/
@Aspect
public class MyAspectjAnno {
@Before(value = "execution(* com.lucifer.aspectj.demo.ProductDao.*(..))")
public void before(){
System.out.println("前置通知==============================");
}
}
test 测试类:
package com.lucifer.aspectj.demo;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @Author: Lucifer
* @Date: 2019/3/21 00:36
* @Description:
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test {
@Autowired
private ProductDao productDao;
@org.junit.Test
public void demo1(){
productDao.save();
productDao.delete();
productDao.findAll();
productDao.findOne();
productDao.update();
}
}
控制台打印:
只匹配com.lucifer.aspectj.demo类下的save()方法:
改变MyAspectjAnno类,将before方法添加JoinPoint 参数;
ps:可以在方法中传入JoinPoint对象,用来获取切点信息
package com.lucifer.aspectj.demo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @Author: Lucifer
* @Date: 2019/3/21 00:31
* @Description: 切面类
*/
@Aspect
public class MyAspectjAnno {
@Before(value = "execution(* com.lucifer.aspectj.demo.ProductDao.save(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知=============================="+joinPoint);
}
}
控制台打印:
pmo.xml:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--引入spring基本的开发包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--aop-->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>spring-aspectj</finalName>
</build>