目前最受歡迎的 AOP 庫有兩個,一個是 AspectJ, 另外一個就是我們今天講的 Spring AOP。
概念部分在先前的篇幅中介紹:https://blog.csdn.net/youhaiguo/article/details/101781682
本篇主要講解Spring Aop的簡單使用。
使用Spring AOP進行編程的實例:
- 修改pom文件中的支持,加入相關依賴
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>
com.springsource.org.aspectj.weaver
</artifactId>
<version>1.6.8.RELEASE</version>
</dependency>
2.1 用xml配置方法進行aop編程:
a. 聲明dao接口和實現類,代碼略。但是要在Impl類上面加上@Componet註解,聲明此類被spring容器託管
b. 聲明service接口和實現類,代碼略。但是要在Impl類上加上@Componet註解,聲明此類被spring容器託管。同時要在Impl類的dao應用上面加上@Autowired,聲明自動注入。
c.新建類TransDemo,聲明4個函數前置、後置、環繞、異常拋出。這個類就是我們的代理,代碼如下:
public class TransDemo {
public void begin(){
System.out.println("start tansaction");
}
public void end(){
System.out.println("end transaction");
}
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("begin transaction");
joinPoint.proceed();
System.out.println("commit transaction");
}
public void thorwExption() throws Exception {
throw new Exception("製造一個異常");
}
}
d. 創建spring配置文件,如下所示:
<?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:p="http://www.springframework.org/schema/p"
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-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
>
<context:component-scan base-package="com.qf.aopdemo"></context:component-scan>
<bean id="transDemo" class="com.qf.aopdemo.tansaction.TransDemo"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.qf.aopdemo.service.*.*.*(..))" id="p1" />
<aop:aspect ref = "transDemo">
<!--前置通知-->
<aop:before method="begin" pointcut-ref="p1" />
<!--後置通知-->
<aop:after-returning method="end" pointcut-ref="p1"/>
<!--環繞通知-->
<aop:around method="around" pointcut-ref="p1"/>
</aop:aspect>
</aop:config>
</beans>
e.新建測試類,代碼如下:
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-aop.xml");
UserService userService = applicationContext.getBean(UserService.class);
UserInfo user = new UserInfo();
user.setAge(19);
user.setName("yangxin");
userService.addUser(user);
userService.deleteUser(user);
}
}
2.2使用註解的方法進行aop編程
a.新建基於註解的切面類,內容如下:
@Aspect
public class TransDemo2 {
//定義切點
@Pointcut(value="execution(* com.qf.aopdemo.*.*.*(..))")
public void point(){
}
@Before(value="point()")
public void before(){
System.out.println("transaction begin before");
}
@AfterReturning(value = "point()")
public void after(){
System.out.println("transaction commit after");
}
@Around("point()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("transaction begin around");
joinPoint.proceed();
System.out.println("transaction commit around");
}
}
b.修改spring-aop.xml,內容如下:
<bean id="transactionDemo2" class = "com.qf.aopdemo.tansaction.TransDemo2"/>
<aop:aspectj-autoproxy />
c.運行測試類,同上。
總結:
Spring Aop的常見註解
a) @Pointcut
b) @Before
c) @AfterReturning
d) @AfterThrowing
e) @After
f) @Around
織入點語法:
a) execution(修飾符 返回類型 方法名(形參列表)):聲明這是一個織入點。
b) 參數模式稍微有點複雜:
i. ()匹配了一個不接受任何參數的方法,
ii. (…)匹配了一個接受任意數量參數的方法(零或者更多)
iii. 模式(*)匹配了一個接受一個任何類型的參數的方法
iv. 模式(*,String)匹配了一個接受兩個參數的方法,第一個可以是任意類型, 第二個則必須是String類型
織入點語法舉例:
a) 任意公共方法的執行:
execution(public * *(…))
b) 任何一個名字以“set”開始的方法的執行:
execution(* set*(…))
c) AccountService接口定義的任意方法的執行:
execution(* com.xyz.service.AccountService.*(…))
d) 在service包中定義的任意方法的執行:
execution(* com.xyz.service..(…))
e) 在service包或其子包中定義的任意方法的執行:
execution(* com.xyz.service….(…))