基於註解的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() { } }
其中第三個切入點使用了自定義的註解類 CustomAnnotation
。apache
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>