Spring使用XML的方式實現AOP的開發——Spring AOP(六)
本章接上一章講,所需jar包和xml的命名引用已經弄好:
https://blog.csdn.net/qq_34598667/article/details/83417459
本章我們講解xml的方式實現aop
Spring使用AspectJ進行AOP的開發:XML的方式
學習本章需要先知道這些內容:
通知型別
前置通知:在目標方法執行之前執行.
後置通知:在目標方法執行之後執行
環繞通知:在目標方法執行前和執行後執行
異常丟擲通知:在目標方法執行出現異常的時候執行
最終通知:無論目標方法是否出現異常最終通知都會執行.
切入點語法表示式
語法:execution(表示式)
表示式語法:[方法訪問修飾符] 方法返回值包名.類名.方法名(方法的引數)
-
例1:
execution (* com.oak.service.impl.UserServiceImpl.*(…)) :匹配UserServiceImpl類中宣告的所有方法。
第一個 * :代表任意修飾符及任意返回值型別
第二個 * :代表任意方法,
… :匹配任意數量任意型別的引數,若目標類與該切面在同一個包中,可以省略包名。 -
例2:execution public double cn.itcast.service.impl.PersonServiceImpl.*(…):匹配PersonServiceImpl類中返回值型別為double型別的所有公有方法。
下面開始我們的案例:
1)匯入jar包和引入xml名稱空間
上一章已經寫好
2)編寫目標類
1)建立介面UserService
public interface UserService {
void save();
void update();
void delete();
void find();
}
2)編寫實現類
public class UserServiceImpl implements UserService{
@Override
public void save() {
System.out.println("I am the method for save " );
}
@Override
public void update() {
System.out.println("I am the method for update ");
}
@Override
public void delete() {
System.out.println("I am the method for delete ");
}
@Override
public void find() {
System.out.println("I am the method for find ");
}
}
3)在xml中配置目標類
<!--配置目標類 -->
<bean id="userService" class="com.oak.service.UserServiceImpl"></bean>
4)編寫一個切面類
public class MyAspect {
public void doBeforeCheck() {
System.out.println("前置通知");
}
public void doAfterReturning() {
System.out.println("後置通知");
}
public void doAfter() {
System.out.println("最終通知");
}
public void doAfterThrowing() {
System.out.println("異常通知");
}
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("進入方法");
Object result = pjp.proceed();
System.out.println("退出方法");
return result;
}
}
5)在xml配置檔案中完成通知(增強)配置
從上可知MyAspect不過就是一個普通的JavaBean。現在要使用Spring配置檔案實現AOP,使它變成為一個切面:
<!--配置切面類-->
<bean id="myAspect" class="com.oak.aop.MyAspect"></bean>
<!--進行aop的配置-->
<aop:config>
<!--配置切入點表示式:哪些類的哪些方法需要進行增強 這裡給UserService的save方法進行增強 -->
<aop:pointcut expression="execution(* com.oak.service.UserService.save(..))" id="pointcut1"/>
<!--配置切面-->
<aop:aspect ref="myAspect">
<!-- 指定before前置通知的方式是切面中的doAccessCheck方法 -->
<aop:before method="doAccessCheck" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
6)測試
在com.oak.test中新建SpringAOPTest,新建aopXmlTest為:
@Test
public void aopXmlTest(){
ApplicationContext cxt =
new ClassPathXmlApplicationContext
("applicationContext.xml");
UserService userService=cxt.getBean("userService",UserService.class);
userService.save();
}
控制檯結果為:
前置通知
I am the method for save
在執行目標類的save方法前執行了代理了的前置通知。
7)其他通知(增強)的配置
修改xml,給UserService中的所有方法新增通知
<!--進行aop的配置-->
<aop:config>
<!--配置切入點表示式:哪些類的哪些方法需要進行增強 這裡給UserService的save方法進行增強 -->
<aop:pointcut expression="execution(* com.oak.service.UserService.save(..))" id="pointcut1"/>
<!-- 給所有的方法增強 -->
<aop:pointcut expression="execution(* com.oak.service.UserService.*(..))" id="pointcut2"/>
<!--配置切面-->
<aop:aspect ref="myAspect">
<!-- 指定before前置通知的方式是切面中的doAccessCheck方法 -->
<aop:before method="doBeforeCheck" pointcut-ref="pointcut1"/>
<!-- 指定after-returning後置通知的方式是切面中的doAfterReturning方法 -->
<aop:after-returning method="doAfterReturning" pointcut-ref="pointcut2"/>
<!-- 異常通知 -->
<aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut2"/>
<!-- 最終通知 -->
<aop:after method="doAfter" pointcut-ref="pointcut2"/>
</aop:aspect>
</aop:config>
修改測試類:
@Test
public void aopXmlTest(){
ApplicationContext cxt =
new ClassPathXmlApplicationContext
("applicationContext.xml");
UserService userService=cxt.getBean("userService",UserService.class);
userService.save();
userService.delete();
}
控制檯結果為:
前置通知
I am the method for save
後置通知
最終通知
I am the method for delete
後置通知
最終通知