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

一、环境准备

<?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 />
</beans>

 二、@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*(..))

 

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

(1)@Before前置通知

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

(2)@AfterReturing 后置通知

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

(3)@Around 环绕通知

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

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

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

(4)@AfterThrowing 异常抛出通知

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

(5)@After 最终通知

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

五、通过@Pointcut为切点命名

在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用@Pointcut进行定义

切点方法:private void 无参数方法,方法名为切点名

当通知多个切点时,可以使用|| 进行连接

 

代码:

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.imooc.aspectJ.demo1.ProductDao"/>

    <!--定义切面-->
    <bean class="com.imooc.aspectJ.demo1.MyAspectAnno"/>
</beans>
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();
        }
    }


}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值