使用AspectJ 需要导入Spring AOP和 AspectJ相关jar包
– spring-aop-4.2.4.RELEASE.jar
– com.springsource.org.aopalliance-1.0.0.jar
– spring-aspects-4.2.4.RELEASE.jar
– com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
• @Before 前置通知,相当于BeforeAdvice
• @AfterReturning 后置通知,相当于AfterReturningAdvice
• @Around 环绕通知,相当于MethodInterceptor
• @AfterThrowing异常抛出通知,相当于ThrowAdvice
• @After 最终final通知,不管是否异常,该通知都会执行
• @DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)
通过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*(..))
(1)@Before前置通知
可以在方法中传入JoinPoint对象,用来获得切点信息
(2)@AfterReturing 后置通知
通过returning属性 可以定义方法返回值,作为参数
(3)@Around 环绕通知
• around方法的返回值就是目标代理方法执行返回值
• 参数为ProceedingJoinPoint 可以调用拦截目标方法执行
重点:如果不调用 ProceedingJoinPoint的 proceed方法,那么目标方法就被拦截了
(4)@AfterThrowing 异常抛出通知
通过设置throwing属性,可以设置发生异常对象参数
(5)@After 最终通知
无论是否出现异常,最终通知总是会被执行的
• 在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用@Pointcut进行定义
• 切点方法:private void 无参数方法,方法名为切点名
• 当通知多个切点时,可以使用|| 进行连接
applicationContext.xml
MyAspectAnno类
/**
* 切面类
*/
@Aspect
public class MyAspectAnno {
@Before(value = "myPointcut1()")
public void before(JoinPoint joinPoint){
System.out.println("前置通知。。。"+joinPoint);
}
@AfterReturning(value = "myPointcut2()",returning = "result")
public void afterReturning(Object result){
System.out.println("后置通知。。。"+result);
}
@Around(value = "myPointcut3()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("前置通知。。。");
Object obj = joinPoint.proceed();
System.out.println("后置通知。。。");
return obj;
}
@AfterThrowing(value = "myPointcut4()",throwing = "e")
public void afterThrowing(Throwable e){
System.out.println("异常抛出通知=========="+e.getMessage());
}
@After(value = "myPointcut5()")
public void after(){
System.out.println("最终通知==========");
}
@Pointcut(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.update(..))")
private void myPointcut1(){}
@Pointcut(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))")
private void myPointcut2(){}
@Pointcut(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.delete(..))")
private void myPointcut3(){}
@Pointcut(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.findOne(..))")
private void myPointcut4(){}
@Pointcut(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.findAll(..))")
private void myPointcut5(){}
}
ProductDao
public class ProductDao {
public void save(){
System.out.println("保存商品...");
}
public String update(){
System.out.println("修改商品...");
return "hello";
}
public void delete(){
System.out.println("删除商品...");
}
public void findOne(){
System.out.println("查询一个商品...");
//int i = 1/0;
}
public void findAll(){
System.out.println("查询所有商品...");
// int j = 1/0;
}
}
SpringDemo1
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {
@Resource(name="productDao")
private ProductDao productDao;
@Test
public void demo1(){
try {
productDao.findAll();
productDao.save();
productDao.update();
productDao.delete();
productDao.findOne();
} catch (Exception e) {
e.printStackTrace();
}
}
}