1. 程式人生 > >Spring使用XML的方式實現AOP的開發——Spring AOP(六)

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 
後置通知
最終通知