基于AspectJ的注解AOP开发

AspectJ简介

环境搭建

使用AspectJ之前需要在pom.xml中引入Spring AOP和AspectJ的相关jar包

 <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>

    <!--aspectj的包依赖以上2个包-->

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.9</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>

 配置文件

按以下内容配置好applicationContext.xml文件,即可开始AOP的注解开发。

<?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 注解提供的通知类型

  1. @Before => 相当于BeforeAdvice(前置通知)
  2. @AfterReturning => 相当于AfterReturningAdvice(后置通知)
  3. @Around => 相当于MethodInterceptor(环绕通知)
  4. @AfterThrowing=> 相当于ThrowAdvice(异常通知)
  5. @After => 相当于try-catch语句的finally,不管是否异常都会通知

value属性定义切点

在为一个方法写通知类型时,需要使用value属性来配置方法对应的切点(也就是拦截的方法)

前置通知的例子

com.aspectJ建了2个类,ProductDao是被代理类,MyAspectAnno是代理类。

 配置文件

<?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.aspectJ.ProductDao"></bean>
    <!-- 配置切面 -->
    <bean class="com.aspectJ.MyAspectAnno"></bean>
</beans>

2个类结构:

编写测试类

    @org.junit.Test
    public void test() {
        // 加载配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext1.xml");
        // 获取bean
        ProductDao productDao = (ProductDao) context.getBean("productDao");
        productDao.save();
        productDao.delete();
    }

运行结果:  

前置增强...execution(void com.aspectJ.ProductDao.save())
保存商品...
删除商品... 

 其它类型通知

后置通知

// 后置通知,拦截update方法
    @AfterReturning(value="execution(* com.aspectJ.ProductDao.update(..))",returning="ret")
    public void afterReturning(Object ret) {
        // ret是拦截的方法返回值
        System.out.println("后置增强" + ret);
    }

 环绕通知

// 环绕通知,拦截所有方法
    @Around(value="execution(* *(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {        
        System.out.println("环绕前增强");
        // 执行拦截到的方法
        Object object = joinPoint.proceed();
        System.out.println("环绕后增强");
        return object;
    }

异常抛出通知

// 异常抛出通知
    @AfterThrowing(value="execution(* *(..))", throwing="e")
    public void throwing(Throwable e) {
        System.out.println("异常抛出通知" + e.getMessage());
    }

最终通知(类似finally) 

// 最终通知
    @After(value="execution(* *(..))")
    public void after() {
        System.out.println("最终通知");
    }

起别名:给要拦截的方法起别名,这样在一个方法需要在多处产生通知时使用别名有利于代码的维护.

value后面写要起别名的方法,下面写一个 private void 别名() {},这样就产生了别名,在使用拦截的地方,把value写成value="别名()"就可以了。

// 给拦截的方法起别名
    @Pointcut(value="execution(* com.aspectJ.ProductDao.update(..))")
    private void myPointCut() {}

 // 后置通知,使用别名
    @AfterReturning(value="myPointCut()",returning="ret")
    public void afterReturning(Object ret) {
        // ret是拦截的方法返回值
        System.out.println("后置增强" + ret);
    }

猜你喜欢

转载自blog.csdn.net/lmhlmh_/article/details/81292543