javascript
Spring 学习二-----AOP的原理与简单实践
一、Spring ?AOP的原理
AOP全名Aspect-Oriented Programming,中文直譯為面向切面(方面)編程。何為切面,就比如說我們系統中的權限管理,日志,事務等我們都可以將其看成一個個切面。
Spring AOP 采用的是動態代理的設計模式來實現切面編程的。
首先,我們可以通過?
23種設計模式----------代理模式(三) 之 動態代理模式
來了解下動態代理模式,再次不再贅述。
我們來看看Spring AOP 是怎樣運用動態代理模式的。在Spring AOP 通過
調用流程如下: 1、實現InvocationHandler接口 2、通過ProxyFactoryBean用于創建代理類(根據Advisor生成的Bean,也就是TargetBean的代理) 3、調用invoke方法? 然后,AOP中幾個重要的概念是: 1、關注點(concern)?? 一個關注點可以是一個特定的問題,概念、或者應用程序的興趣點??偠灾?#xff0c;應用程序必須達到一個目標
?? 安全驗證、日志記錄、事務管理都是一個關注點
?? 在oo應用程序中,關注點可能已經被代碼模塊化了還可能散落在整個對象模型中
2、橫切關注點(crosscutting concern)
?? 如何一個關注點的實現代碼散落在多個類中或方法中
3、方面(aspect)
?? 一個方面是對一個橫切關注點模塊化,它將那些原本散落在各處的,
?? 用于實現這個關注點的代碼規整在一處,可以通過@Aspect標注或在applictionContext.xml中進行配置:? <aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2"> 4、建議(advice)通知
?? advice是point cut執行代碼,是方面執行的具體實現,如 <aop:aspect ref="advices"><!--切點--><aop:pointcut id="pointcut1" expression="execution(* com.jay.springAOP.aop01.Math.*(..))"/><!--連接通知方法與切點--><aop:before method="before" pointcut-ref="pointcut1"/><aop:after method="after" pointcut-ref="pointcut1"/></aop:aspect> 5、切入點(pointcut)
?? 用于指定某個建議用到何處 <aop:pointcut id="myPointcut" expression="execution(* com.wicresoft.app.service.impl.*.*(..))" method="release" /> 6、織入(weaving)
?? 將aspect(方面)運用到目標對象的過程
7、連接點(join point)
? 程序執行過程中的一個點?
?通知類型
try{
//前置通知
//環繞通知
//調用目標對象方法
//環繞通知
//后置通知
}catch(){
//異常通知
}finally{
//終止通知
}
?
?
注:圖片來源于:http://blog.csdn.net/lirui0822/article/details/8555691?
關于PointCut中使用的execution的說明:
execution(modifiers-pattern??ret-type-pattern?declaring-type-pattern??name-pattern(param-pattern)?throws-pattern?)?
modifiers-pattern:方法的操作權限
ret-type-pattern:返回值
declaring-type-pattern:方法所在的包
name-pattern:方法名
parm-pattern:參數名
throws-pattern:異常
記憶法則就是Java定義一個方法時的樣子:public boolean produceValue(int oo) throws Exception, 只要在方法名前加上包名就可以了。
其中,除ret-type-pattern和name-pattern之外,其他都是可選的。上例中,execution(* com.spring.service.*.*(..))表示com.spring.service包下,返回值為任意類型;方法名任意;參數不作限制的所有方法。
二、Spring AOP的簡單實踐
1、首先定義一個日志切面,采用前置通知
package com.jay.springAOP.aopDecorator;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* 一個用于記錄日志的切面
* Created by xiang.wei on 2017/8/14.
*/
@Component
@Aspect
public class LoggerAdvices {
@Before("execution(* com.jay.springAOP.aopDecorator.*.*(..))")
public void addLogger(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName());
Logger logger= LoggerFactory.getLogger(this.getClass());
//記錄日志
logger.debug("-------起始操作----------");
logger.debug("-------結束操作-----------");
}
}
2、定義一個用于性能統計的切面,其中定義了一個環繞通知
package com.jay.springAOP.aopDecorator;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component;/*** 一個用于性能的統計* Created by xiang.wei on 2017/8/14.*/ @Component @Aspect public class PerformanceAdvices {@Around("execution(* com.jay.springAOP.aopDecorator.*.*(..))")public Object execute(ProceedingJoinPoint pjp) throws Throwable {System.out.println(pjp.getSignature().getName());System.out.println("開始時間:"+System.currentTimeMillis());Object result = pjp.proceed();System.out.println("結束時間:"+System.currentTimeMillis());return result;} }3、相關的業務代碼
package com.jay.springAOP.aopDecorator;import org.springframework.stereotype.Service;/*** Created by xiang.wei on 2017/8/14.*/ @Service("paymentCommand") public class PaymentCommand {public void pay() {//執行下訂單操作int j=0;for (int i=0;i<10000;i++ ) {j++;}//執行支付操作System.out.println("進行支付");} } package com.jay.springAOP.aopDecorator;import org.springframework.stereotype.Service;/*** Created by xiang.wei on 2017/8/14.*/ @Service("placeOrderCommand") public class PlaceOrderCommand{public void handleOrder() {//執行下訂單操作int j=0;for (int i=0;i<100000;i++ ) {j++;}System.out.println("進行下單操作");} }4、測試類:
package com.jay.springAOP.aopDecorator;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;/*** Created by xiang.wei on 2017/8/15.*/ public class Client {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("aopDecorator.xml");PlaceOrderCommand placeOrderCommand = ctx.getBean("placeOrderCommand", PlaceOrderCommand.class);placeOrderCommand.handleOrder();PaymentCommand paymentCommand = ctx.getBean("paymentCommand",PaymentCommand.class);paymentCommand.pay();} }測試結果如下:
?
?
轉載于:https://www.cnblogs.com/Fly-Bob/p/7368129.html
總結
以上是生活随笔為你收集整理的Spring 学习二-----AOP的原理与简单实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jquer 的简输出
- 下一篇: gradle idea java ssm