spring-aop-01
阿新 • • 發佈:2018-11-25
aop實現初步
applicationContext.xml配置內容
<context:annotation-config /> <context:component-scan base-package="cn.mldn" /> <!-- 如果要想讓切面控制有效,那麼必須將此類的物件交由Spring進行管理 --> <bean id="serviceProxy" class="cn.mldn.aop.ServiceProxy"/> <aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 要求進入AOP的配置,重點配置切入點,以及確定切入的處理方法 --> <aop:config> <!-- execution(修飾符匹配? 返回值型別匹配 操作型別匹配? 名稱匹配(引數匹配) 丟擲異常匹配 ) : 主要是用於定義切入點的執行語法 --> <!-- 本次操作裡面沒有編寫修飾符 ,如果要編寫可以使用 public private編寫,可以出現0次或一次 如:"execution(public * cn.mldn..*.*(..))"--><!-- "*" : 表示返回值,即支援所有型別的返回值 --> <!-- cn.mldn.. : 描述的是包名稱的匹配 ,如果是 “..” 表示任意的子包下控制 --> <!-- *.* : 描述的是“類.方法” ,*。* 表示所有的類與所有的方法 --> <!-- .. : 描述的是引數 , “..” 表示任意的引數 --> <aop:pointcut expression="execution(* cn.mldn.service..*.*(..))"id="pointCut"/> <!-- 設定切入點 --> <aop:aspect ref="serviceProxy"> <!-- 進行切面的配置 , 如果是切面控制應該有一個控制的類 --> <!-- 不同的切面處理操作可以使用同一個切入點,或者每一個操作來定義屬於自己的切入點 --> <aop:before method="beforeMethod" pointcut-ref="pointCut"/> <aop:after method="afterMethod" pointcut-ref="pointCut"/> </aop:aspect> </aop:config>
Service
package cn.mldn.service.impl; import org.springframework.stereotype.Service; import cn.mldn.service.IMemberService; @Service public class MemberServiceImpl implements IMemberService { @Override public boolean delete(String mid) throws Exception { System.out.println("[MemberService] 資料刪除處理"); return false; } }
package cn.mldn.service;
public interface IMemberService {
public boolean delete(String mid) throws Exception ;
}
proxy
package cn.mldn.aop; public class ServiceProxy { public void beforeMethod() { System.out.println("###### [ServiceProxy] public void beforeMethod(){}"); } public void afterMethod() { System.out.println("###### [ServiceProxy] public void afterMethod(){}"); } }
test
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); IMemberService ms = ctx.getBean("memberServiceImpl" ,MemberServiceImpl.class) ; ms.delete("123");
result
###### [ServiceProxy] public void beforeMethod(){} [MemberService] 資料刪除處理 ###### [ServiceProxy] public void afterMethod(){}
切面函式配置引數
public class ServiceProxy { public void beforeMethod(Object obj) { System.out.println("###### [ServiceProxy] public void beforeMethod(){} ,引數內容:"+obj); } public void afterMethod() { System.out.println("###### [ServiceProxy] public void afterMethod(){}"); } }
<aop:pointcut expression="execution(* cn.mldn.service..*.*(..)) and args(id)" id="pointCut"/> <aop:aspect ref="serviceProxy"> <!-- 上面的args裡面的id與arg-names的id是一至的 --> <aop:before method="beforeMethod" pointcut-ref="pointCut" arg-names="id"/> <aop:after method="afterMethod" pointcut="execution(* cn.mldn.service..*.*(..))"/> </aop:aspect>
其他配置
<aop:aspect ref="serviceProxy"> <!-- 進行切面的配置 , 如果是切面控制應該有一個控制的類 --> <!-- 不同的切面處理操作可以使用同一個切入點,或者每一個操作來定義屬於自己的切入點 --> <aop:before method="beforeMethod" pointcut-ref="pointCut" arg-names="id"/> <aop:after method="afterMethod" pointcut="execution(* cn.mldn.service..*.*(..))"/> <!-- 返回值切面 v 只是個標記,隨便寫 ,只是接收,不能更改--> <aop:after-returning method="returnMethod" pointcut="execution(* cn.mldn.service..*.*(..))" returning="v" arg-names="v"/> <!-- 針對異常進行處理, --> <aop:after-throwing method="throwMethod" pointcut="execution(* cn.mldn.service..*.*(..))" throwing="e" arg-names="e"/>
<!-- 環繞通知的配置 -->
<aop:around method="aroundMethod" pointcut="execution(* cn.mldn.service..*.*(..))"/>
</aop:aspect>
package cn.mldn.aop; public class ServiceProxy { public void beforeMethod(Object obj) { System.out.println("###### [ServiceProxy] public void beforeMethod(){} ,引數內容:"+obj); } public void afterMethod() { System.out.println("###### [ServiceProxy] public void afterMethod(){}"); } public void returnMethod(Object val) { //處理返回值 System.out.println("###### [ServiceProxy] public void returnMethod(){} ,返回值:" + val); } public void throwMethod(Exception e) { // 對異常進行處理 System.out.println("###### [ServiceProxy] public void throwMethod(){} 異常資訊:" + e ); }
public Object aroundMethod(ProceedingJoinPoint point) throws Throwable { //呼叫具體的執行方法
System.out.println("@@@@@@ aroundMethod() - before 引數:" + new Arrays().toString(point.getArgs()));
//此時可以正對於引數接收後處理後再傳遞的操作
Object obj = point.proceed(new Object [] {"abc"});
System.out.println("@@@@@@ aroundMethod() - after 返回結果:" + obj);
return true ; //還可以不按照結果返回資料
}
}
aop annotation
package cn.mldn.aop; import org.apache.catalina.tribes.util.Arrays; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class ServiceProxy { @Before(value="execution(* cn.mldn.service..*.*(..)) and args(id)",argNames="id") public void beforeMethod(Object obj) { System.out.println("###### [ServiceProxy] public void beforeMethod(){} ,引數內容:"+obj); } @After(value="execution(* cn.mldn.service..*.*(..))") public void afterMethod() { System.out.println("###### [ServiceProxy] public void afterMethod(){}"); } @AfterReturning(value="execution(* cn.mldn.service..*.*(..))",returning="v",argNames="v") public void returnMethod(Object val) { //處理返回值 System.out.println("###### [ServiceProxy] public void returnMethod(){} ,返回值:" + val); } @AfterThrowing(value="execution(* cn.mldn.service..*.*(..))",throwing="e",argNames="e") public void throwMethod(Exception e) { // 對異常進行處理 System.out.println("###### [ServiceProxy] public void throwMethod(){} 異常資訊:" + e ); } @Around(value="execution(* cn.mldn.service..*.*(..))") public Object aroundMethod(ProceedingJoinPoint point) throws Throwable { //呼叫具體的執行方法 System.out.println("@@@@@@ aroundMethod() - before 引數:" + new Arrays().toString(point.getArgs())); //此時可以正對於引數接收後處理後再傳遞的操作 Object obj = point.proceed(new Object [] {"abc"}); System.out.println("@@@@@@ aroundMethod() - after 返回結果:" + obj); return true ; //還可以不按照結果返回資料 } }