spring AOP的兩種配置方式
阿新 • • 發佈:2018-01-26
can 之前 top () 就是 記錄 string -s 服務
連接點(JoinPoint) ,就是spring允許你是通知(Advice)的地方,那可就真多了,基本每個方法的前、後(兩者都有也行),或拋出異常是時都可以是連接點,spring只支持方法連接點。其他如AspectJ還可以讓你在構造器或屬性註入時都行,不過那不是咱們關註的,只要記住,和方法有關的前前後後都是連接點。
方式一:xml方式配置
1.配置xml文件
<bean id="dataSourceExchange" class="com.ooper.www.datasource.DataSourceExchange"/> <!--輔助功能bean--> <aop:config> <aop:pointcut id="dataSourcePointcut" expression="execution(* com.ooper.www.service.Impl.AccountServiceImpl.*(..))"/> <!-- 指定核心業務功能 --> <aop:aspect ref="dataSourceExchange"> <!--指定輔助功能 --> <aop:before pointcut-ref="dataSourcePointcut" method="before"/><!-- 執行核心任務之前執行 --> <aop:after pointcut-ref="dataSourcePointcut" method="after"/><!-- 執行核心任務之後執行 --> </aop:aspect> </aop:config>
2. 輔助功能java代碼
package com.ooper.www.datasource; import org.aspectj.lang.JoinPoint;public class DataSourceExchange { public void before(JoinPoint point) { //獲取目標對象的類類型 Class<?> aClass = point.getTarget().getClass(); String c = aClass.getName(); String[] ss = c.split("\\."); //獲取包名用於區分不同數據源 String methodName = ss[5]; if ("AccountServiceImpl".equals(methodName)) { DataSourceHolder.setDbType(DataSourceEnum.DS2.getKey()); System.out.println("數據源:"+DataSourceEnum.DS2.getKey()); } else { DataSourceHolder.setDbType(DataSourceEnum.DS1.getKey()); System.out.println("數據源:"+DataSourceEnum.DS1.getKey()); } } /** * 執行後將數據源置為空 */ public void after(JoinPoint point) { System.out.println("point:" + point); DataSourceHolder.setDbType(null); } }
方式二:註解方式
1.xml配置文件
<!-- 註解方式實現AOP --> <!-- 激活自動代理功能 --> <!-- 代理方式1:采用JDK代理 --> <aop:aspectj-autoproxy/> <!-- 代理方式2:cglib代理 --> <!-- <aop:aspectj-autoproxy proxy-target-class="true"/> --> <!-- 找到被註解了的切面類,進行切面配置 --> <context:component-scan base-package="com.how2java.aspect"/> <context:component-scan base-package="com.how2java.controller"/>
2.註解配置切面代碼
package com.how2java.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /**spring AOP 此段小代碼演示了spring aop中@Around @Before @After三個註解的區別 * @Before是在所攔截方法執行之前執行一段邏輯。@After 是在所攔截方法執行之後執行一段邏輯。@Around是可以同時在所攔截方法的前後執行一段邏輯。 * @author Administrator * 通過aop攔截後執行具體操作 */ @Aspect @Component public class LogIntercept { // @Pointcut("execution(* com.how2java.controller..*.*(..))") public void recordLog(){} @Before("execution(* com.how2java.controller..*.*(..))") // @Before("recordLog()") public void before() { this.printLog("已經記錄下操作日誌@Before 方法執行前"); } @Around("execution(* com.how2java.controller..*.*(..))") // @Around("recordLog()") public Object around(ProceedingJoinPoint pjp) throws Throwable{ this.printLog("已經記錄下操作日誌@Around 方法執行前"); Object obj = pjp.proceed(); this.printLog("已經記錄下操作日誌@Around 方法執行後"); return obj; } @After("execution(* com.how2java.controller..*.*(..))") // @After("recordLog()") public void after() { this.printLog("已經記錄下操作日誌@After 方法執行後"); } private void printLog(String str){ System.out.println(str); } }
package com.how2java.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect // 註解表示這是一個切面 @Component //表示這是一個bean,由Spring進行管理,使用註解時一定要使用@component或者@Repository、@Controller、@Service中一個去聲明,將切面類放入到spring容器中,不然就去xml中顯式寫一個bean,不然的話就會報錯,無法實現切面功能。 public class LoggerAspect { @Around(value = "execution(* com.how2java.controller..*.*(..))") //表示對com.how2java.controller 這個包中的所有方法進行切面操作 /* AOP(execution表達式) * * execution(* com.how2java.controller..*.*(..)) 解釋如下: 符號 含義 execution() 表達式的主體; 第一個”*“符號 表示返回值的類型任意; com.how2java.controller AOP所切的服務的包名,即,我們的業務部分 包名後面的”..“ 表示當前包及子包 第二個”*“ 表示類名,*即所有類。此處可以自定義,下文有舉例 .*(..) 表示任何方法名,括號表示參數,兩個點表示任何參數類型 */ public Object log(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("start log:" + joinPoint.getSignature().getName()); Object object = joinPoint.proceed();//就是將來與某個核心功能編織之後,用於執行核心功能的代碼 System.out.println("end log:" + joinPoint.getSignature().getName()); return object; } }
spring AOP的兩種配置方式