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*(…))
代码实现
ProductDao.java
package com.shunli.aspect.demo1;
public class ProductDao {
public void save(){
System.out.println("save......");
}
public String update(){
System.out.println("update......");
return "update return";
}
public void find(){
System.out.println("find......");
}
public void findAll(){
System.out.println("findAll......");
}
public void delete(){
System.out.println("delete......");
int i = 1/0;//异常
}
}
MyAspectAnno.java
package com.shunli.aspect.demo1;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
/**
* @author shunli
* 切面类
*/
@Aspect
public class MyAspectAnno {
//设置save方法为前置通知
@Before(value = "execution(* com.shunli.aspect.demo1.ProductDao.save(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知......" + joinPoint);
}
//设置update方法为后置通知
@AfterReturning(value = "execution(* com.shunli.aspect.demo1.ProductDao.update(..))", returning = "result")
public void afterReturing(Object result){
System.out.println("后置通知=================="+result);
}
//设置find方法为环绕通知
@Around(value = "execution(* com.shunli.aspect.demo1.ProductDao.find(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前通知================");
// 执行目标方法
Object obj = joinPoint.proceed();
System.out.println("环绕后通知================");
return obj;
}
//设置findAll为最终通知
@After(value = "execution(* com.shunli.aspect.demo1.ProductDao.findAll(..))")
public void after(){
System.out.println("最终通知==================");
}
//设置delete方法为异常抛出通知
@AfterThrowing(value = "myPointcut()", throwing = "e")
public void afterThrowing (Throwable e){
System.out.println("异常抛出通知==============" + e.getMessage());
}
//上面的value也可以用myPointcut代替
@Pointcut(value="execution(* com.shunli.aspect.demo1.ProductDao.delete(..))")
private void myPointcut(){}
}
applictionContext.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.shunli.aspect.demo1.ProductDao"/>
<!--定义切面-->
<bean class="com.shunli.aspect.demo1.MyAspectAnno"/>
</beans>
SpringDemo1.java中
package com.shunli.aspect.demo1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applictionContext.xml")
public class SpringDemo1 {
@Resource(name = "productDao")
private ProductDao productDao;
@Test
public void demo1(){
productDao.save();
productDao.update();
productDao.find();
productDao.findAll();
productDao.delete();
}
}
输出结果