基於註解的Spring AOP示例

基於註解的Spring AOP示例

在XML配置文件中開啓 @AspectJ 支持

要使用Spring的AOP,首先要在 applicationContext.xml 配置文件中添加以下內容:java

<!-- 啓動@Aspectj -->
<aop:aspectj-autoproxy/>

聲明切面及切入點

在Spring中, 切面 就是使用 @Aspect 註解的類。而 切入點 則由兩部分組成:方法簽名和切入點表達式。下面的切面中聲明瞭三種切入點。spring

@Aspect
public class SampleAspect {
    // 匹配全部的公共方法
    @Pointcut("execution(public * *(..))")
    public void publicMethod() {
    }

    // 匹配全部在com.app.bean包中的方法
    @Pointcut("within(com.app.bean.*)")
    public void inPackage() {
    }

    // 匹配全部帶有CustomAnnotation註解的方法
    @Pointcut("@annotation(com.app.annotation.CustomAnnotation)")
    public void withAnnotation() {
    }
}

其中第三個切入點使用了自定義的註解類 CustomAnnotationapache

public @interface CustomAnnotation {}

聲明通知

接下來要聲明的是 通知 ,通知與切面的結構基本一致。不一樣的是通知使用 @Before@Around 等註解同切面中的切入點一塊兒肯定執行的方法。下面的通知示例中聲明瞭三種通知方式,其中 @Around 類型的通知須要一個 ProceedingJoinPoint 類的實例做爲參數。app

@Aspect
public class SampleAdvice {
    @Before("com.app.aspect.SampleAspect.publicMethod()")
    public void advicePublicMethod() {
        System.out.println("before advice matched with public methods");
    }

    @After("com.app.aspect.SampleAspect.inPackage()")
    public void adviceInBean() {
        System.out.println("after advice matched methods in package");
    }

    @Around("com.app.aspect.SampleAspect.withAnnotation()")
    public Object adviceWithAnnotation(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("around advice before proceed");
        Object ret = jp.proceed();
        System.out.print("around advice after proceed");
        return ret;
    }
}

以前聲明的切面和通知都須要在配置文件中聲明一下,最終的 applicationContext.xml 以下所示:maven

<?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:context="http://www.springframework.org/schema/context"
       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/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">
  <context:component-scan base-package="com.app"/>
  <!-- 啓動@Aspectj -->
  <aop:aspectj-autoproxy/>

  <!-- 切面 -->
  <bean id="sampleAspect" class="com.app.aspect.SampleAspect"/>
  <!-- 通知 -->
  <bean id="sampleAdvice" class="com.app.aspect.SampleAdvice"/>
</beans>

測試

如今能夠寫一個普通的類來測試咱們的代碼了,在 com.app.bean 包中建立文件:測試

@Component
public class CommonService {
    public void service() {
        System.out.println("service method");
    }

    public void transfer() {
        System.out.println("transfer method");
    }

    @CustomAnnotation
    public void annotated() {
        System.out.println("method with annotation");
    }
}

測試代碼以下:spa

public class Test {
    public static void main(String[] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        CommonService service = context.getBean("commonService", CommonService.class);
        service.service();
        service.transfer();
        service.annotated();
    }
}

結語

本文中的示例代碼是基於Maven項目的,最終代碼的包結構以下:3d

pom.xml 文件內容:code

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.eagle</groupId>
  <artifactId>springDemo</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.0.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.2</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.8.2</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
  </dependencies>
</project>
相關文章
相關標籤/搜索