Spring_使用注解创建切面

读万卷书,行万里路。

定义切面

  在使用AspectJ注解定义切面时,需要引入aspectjrt.jar 和 aspectjweaver.jar

  1.使用@Aspect注解标注类为切面。

  2.使用以下AspectJ注解来声明切面通知方法:

    1)@After:通知方法在目标方法返回或抛出异常后调用;

    2)@AfterReturning:通知方法在目标方法返回后调用;

    3)@AfterThrowing:通知方法在目标方法抛出异常后调用;

    4)@Around:通知方法将目标方法封装起来;

    5)@Before:通知方法在目标方法调用之前执行。

  如下,使用AspectJ注解将普通的POJO类标注为切面:

package chapter4.practice1;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
 * POJO
 * 使用@Aspect标注该POJO也是切面
 */
@Aspect
public class Audience {
    /**
     * 在chapter4.practice1.Performance类的perform方法调用前执行
     */
    @Before("execution(** chapter4.practice1.Performance.perform(..))")
    public void drink() {
        System.out.println("Drink water...");
    }
    
    /**
     * 在chapter4.practice1.Performance类的perform方法返回后执行
     */
    @AfterReturning("execution(** chapter4.practice1.Performance.perform(..))")
    public void eat() {
        System.out.println("Eat food...");
    }
    
    /**
     * 在chapter4.practice1.Performance类的perform方法抛出异常后执行
     */
    @AfterThrowing("execution(** chapter4.practice1.Performance.perform(..))")
    public void refund() {
        System.out.println("Demand refund...");
    }
    
}

  

  在上述代码中可发现相同的切点表达式重复定义了三次,我们可以使用@Pointcut注解在@AspectJ切面定义可重复使用的切点。

package chapter4.practice1;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
 * POJO
 * 使用@Aspect标注该POJO也是切面
 */
@Aspect
public class Audience {
    /**
     * 使用@Pointcut设置切点表达式
     */
    @Pointcut("execution(** chapter4.practice1.Performance.perform(..))")
    public void performance() {}
    
    /**
     * 在chapter4.practice1.Performance类的perform方法调用前执行
     */
    @Before("performance()")
    public void drink() {
        System.out.println("Drink water...");
    }
    
    /**
     * 在chapter4.practice1.Performance类的perform方法返回后执行
     */
    @AfterReturning("performance()")
    public void eat() {
        System.out.println("Eat food...");
    }
    
    /**
     * 在chapter4.practice1.Performance类的perform方法抛出异常后执行
     */
    @AfterThrowing("performance()")
    public void refund() {
        System.out.println("Demand refund...");
    }
    
}

 

启用自动代理

  以上代码创建了一个简单切面,我们还需启用自动代理,这样@Aspect标注的类才会被视为切面,这些注解才会被解析。启用自动代理的方式以下两种:

  1.在Java配置类JavaConfig使用@EnableAspectJAutoProxy注解启用自动代理功能。

package chapter4.practice1;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class JavaConfig {
    
    @Bean
    public Audience audience() {
        return new Audience();
    }
}

 

  2.在XML配置中使用Spring AOP命名空间中的<aop:aspectj-autoproxy>元素启用自动代理功能。

<?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"
    xmlns:c="http://www.springframework.org/schema/c"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc 
http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"
> <context:component-scan base-package="chapter4.practice1" /> <aop:aspectj-autoproxy/> <bean id="audience" class="chapter4.practice1.Audience"></bean> </beans>

 

  Spring的AspectJ自动代理仅使用@AspectJ作为创建切面的指导,切面依然是基于代理的。如果想利用AspectJ的所有功能,必须在运行时使用AspectJ并且不依赖Spring来创建基于代理的切面。

posted @ 2018-04-23 22:46  学而时习之,不亦说乎?  阅读(2493)  评论(0编辑  收藏  举报