使用AspectJ 实现AOP(注解方式)

使用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

一、环境准备





 二、@AspectJ提供不同的通知类型

@Before 前置通知,相当于BeforeAdvice

@AfterReturning 后置通知,相当于AfterReturningAdvice

@Around 环绕通知,相当于MethodInterceptor

@AfterThrowing异常抛出通知,相当于ThrowAdvice

@After 最终final通知,不管是否异常,该通知都会执行

@DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)

三、在通知中通过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*(..))

 

四、为目标类,定义切面类

使用AspectJ 实现AOP(注解方式)_第1张图片

(1)@Before前置通知

可以在方法中传入JoinPoint对象,用来获得切点信息

使用AspectJ 实现AOP(注解方式)_第2张图片

(2)@AfterReturing 后置通知

通过returning属性 可以定义方法返回值,作为参数

(3)@Around 环绕通知

around方法的返回值就是目标代理方法执行返回值

参数为ProceedingJoinPoint 可以调用拦截目标方法执行

使用AspectJ 实现AOP(注解方式)_第3张图片

重点:如果不调用 ProceedingJoinPoint的 proceed方法,那么目标方法就被拦截了

(4)@AfterThrowing 异常抛出通知

通过设置throwing属性,可以设置发生异常对象参数

(5)@After 最终通知

无论是否出现异常,最终通知总是会被执行的

五、通过@Pointcut为切点命名

在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用@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();
        }
    }


}

 

你可能感兴趣的:(Spring)