1、AOP的概念
A、連接點(JoinPoint)
業務代碼與服務器連接的位置
B、通知(Advice)
通知是連接點(JoinPoint)的具體行爲,有幾種通知:
1)置前通知
2)置後通知
3)環繞通知
C、切入點(PointCut)
橫切關注點(服務代碼)織入到哪些類中
D、切面(Aspect)
橫切關注點的實現叫切面
切面 = 切入點 + 通知
——前面的類B就是切面
E、目標對象(Target)
業務對象
——前面的類A就是目標對象
在代碼實現中,我們只要定義一個切面(Aspect)就可以了。
首先,我們定義一個切面類(HelloAspect):
public class HelloAspect {
public void beforeService(){
System.out.println("日誌開始了");
}
public void afterService(){
System.out.println("日誌結束了");
}
public void aroundService(ProceedingJoinPoint pjp){
System.out.println("日誌開始時間"+new Date());
try {
pjp.proceed(); //執行業務方法
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("日誌結束時間"+ new Date());
}
}
再定義一個業務類(HelloService):
public class HelloService {
public void hello1(){
System.out.println("我是類的業務方法1。。。");
}
public void hello2(){
System.out.println("我是類的業務方法2");
}
public void hello3(){
System.out.println("我是類的業務方法3");
}
}
通過Schema來實現AOP
<bean id="HServie" class="cn.gson.springmavenTest.aspect.HelloService"></bean>
<bean id="HAspect" class="cn.gson.springmavenTest.aspect.HelloAspect"></bean>
<aop:config>
<aop:aspect ref="HAspect">
<aop:before method="beforeService"
pointcut="execution(* cn.gson.springmavenTest.aspect.HelloService.hello1(..))" />
<aop:after method="afterService"
pointcut="execution(* cn.gson.springmavenTest.aspect.HelloService.hello2(..))"/>
<aop:around method="aroundService"
pointcut="execution(* cn.gson.springmavenTest.aspect.HelloService.hello3(..))"/>
</aop:aspect>
</aop:config>
測試:
ApplicationContext ac =
new ClassPathXmlApplicationContext("appaicationContext.xml");
HelloService hs = ac.getBean(HelloService.class);
hs.hello1();
hs.hello2();
hs.hello3();
運行結果:
日誌開始了
我是類的業務方法1。。。
我是類的業務方法2
日誌結束了
日誌開始時間Tue Jun 13 09:35:14 CST 2017
我是類的業務方法3
日誌結束時間Tue Jun 13 09:35:14 CST 2017
零配置的方式:
/**
* 切面類
*/
@Component
@Aspect
public class HelloAspect {
@Before(value="execution(* cn.gson.springmavenTest.aspect.HelloService.hello1(..))")
public void beforeService(){
System.out.println("日誌開始了");
}
@After(value="execution(* cn.gson.springmavenTest.aspect.HelloService.hello2(..))")
public void afterService(){
System.out.println("日誌結束了");
}
@Around(value="execution(* cn.gson.springmavenTest.aspect.HelloService.hello3(..))")
public void aroundService(ProceedingJoinPoint pjp){
System.out.println("日誌開始時間"+new Date());
try {
pjp.proceed(); //執行業務方法
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("日誌結束時間"+ new Date());
}
}
xml中開啓註解
<!-- 啓用AOP的註解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="HServie" class="cn.gson.springmavenTest.aspect.HelloService"></bean>
<bean id="HAspect" class="cn.gson.springmavenTest.aspect.HelloAspect"></bean>
注意:
execution表達式
execution表達式是切入點(PointCut)中使用的一種模式,比如
execution(* com.sample.service.impl...(..))
第一個號:表示返回類型,號表示所有的類型。
包名:表示需要攔截的包名,後面的兩個句點表示當前包和當前包的所有子包,com.sample.service.impl包、子孫包下所有類的方法。
第二個號:表示類名,號表示所有的類。
(..):最後這個星號表示方法名,號表示所有的方法,後面括弧裏面表示方法的參數,兩個句點表示任何參數。