Spring實作AOP
1、什么是 AOP
AOP (Aspect Orient Programming),直譯過來就是 面向切面編程,AOP 是一種編程思想,是面向物件編程(OOP)的一種補充,面向物件編程將程式抽象成各個層次的物件,而面向切面編程是將程式抽象成各個切面,

從該圖可以很形象地看出,所謂切面,相當于應用物件間的橫切點,我們可以將其單獨抽象為單獨的模塊,
2、AOP的實作
【重要】:使用AOP需要匯入依賴包
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
方式一:使用Spring的API介面【主要SpringAPI介面實作】
-
xml配置:
<!--注冊bean--> <bean id="userService" class="com.spong.demo03.UserServiceImpl"/> <bean id="logBefore" class="com.spong.demo03.LogBefore"/> <bean id="logAfter" class="com.spong.demo03.LogAfter"/> <!--方式一: 使用原生的Spring API介面--> <!--配置aop:需要匯入aop的約束--> <aop:config> <!--切入點:expression:運算式,execution(要執行的位置: * * * ...)--> <aop:pointcut id="pointcut" expression="execution(* com.spong.demo03.UserServiceImpl.*(..))"/> <!--執行環繞增加--> <aop:advisor advice-ref="logAfter" pointcut-ref="pointcut"/> <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/> </aop:config> -
需要切入的類(實作aop包下的介面MethodBeforeAdvice、AfterReturningAdvice等)
public class LogBefore implements MethodBeforeAdvice { /** * * @param method 要執行的目標物件的方法 * @param objects 方法引數 * @param o 目標物件 * @throws Throwable */ public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println(o.getClass().getName()+"的"+method.getName()+"執行"); } }public class LogAfter implements AfterReturningAdvice { /** * * @param returnValue 方法執行后的回傳值 * @param method * @param args * @param target * @throws Throwable */ public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"方法執行,回傳值為"+returnValue); } }
方式二:自定義類來實作AOP【主要是切面定義】
-
自定義類:
public class Diy { public void logBefore(){ System.out.println("方法執行前"); } public void logAfter(){ System.out.println("方法執行后"); } } -
xml配置:
<!--方式二: 自定義類--> <bean id="diy" class="com.spong.demo03.Diy"/> <aop:config> <aop:aspect ref="diy"> <aop:pointcut id="pointcut" expression="execution(* com.spong.demo03.UserServiceImpl.*(..))"/> <aop:before method="logBefore" pointcut-ref="pointcut"/> <aop:after method="logAfter" pointcut-ref="pointcut"/> </aop:aspect> </aop:config>
方式三:使用注解實作
-
使用注解實作的切面類:
//使用注解實作AOP @Aspect //標注為一個切面 @Component //注入bean public class AnnotationPointCut { //設定切入點 @Pointcut("execution(* com.spong.demo03.UserServiceImpl.*(..))") private void pointCut(){} @Before("pointCut()") public void logBefore(){ System.out.println("方法執行前"); } @After("pointCut()") public void logAfter(){ System.out.println("方法執行后"); } @Around("pointCut()") //環繞增強,我們可以給定一個引數,代表我們要獲取處理切入的點; public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("環繞前"); System.out.println(joinPoint.getSignature()); //獲得簽名(呼叫了哪個類的哪個方法) Object proceed = joinPoint.proceed(); System.out.println("環繞后"); } } -
xml配置:
<!--開啟aop注解支持--> <aop:aspectj-autoproxy/> <!--開啟注解支持--> <context:component-scan base-package="com.spong.demo03"/> <context:annotation-config></context:annotation-config> -
測驗類
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //這里回傳的是一個代理類實體,代理類也是實作了UserService介面 UserService userService = context.getBean("userService", UserService.class); userService.add(); } } -
測驗結果:
環繞前 void com.spong.demo03.UserService.add() 方法執行前 add 方法執行后 環繞后
切入點運算式execution (* com.sample.service..*. *(..))決議:
整個運算式可以分為五個部分:
1、execution()::運算式主體,
2、第一個*號:表示回傳型別, *號表示所有的型別,
3、包名:表示需要攔截的包名,后面的兩個句點表示當前包和當前包的所有子包,com.sample.service包、子孫包下所有類的方法,
4、第二個號:表示類名,號表示所有的類,
5、(..):最后這個星號表示方法名,號表示所有的方法,后面括弧里面表示方法的引數,兩個句點表示任何引數
如有錯誤,歡迎大佬指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/84966.html
標籤:Java
