Spring之Aop練習
注意一下,在講解之前,說明一點:使用Spring AOP,要成功執行起程式碼,只用Spring提供給開發者的jar包是不夠的,請額外上網下載兩個jar包:
1、aopalliance.jar
2、aspectjweaver.jar
開始講解用Spring AOP的XML實現方式,先定義一個介面:
package cn.itcast.oa.service;
public interface HelloWorld {
void printHelloWorld();
void doPrint();
}
兩個實現類:
package cn.itcast.oa.service.impl;
import cn.itcast.oa.service.HelloWorld;
public class HelloWorldImpl1 implements HelloWorld {
public void printHelloWorld() {
System.out.println("Enter HelloWorldImpl1.printHelloWorld()");
}
public void doPrint() {
System.out.println("Enter HelloWorldImpl1.doPrint()");
return;
}
}
package cn.itcast.oa.service.impl;
import cn.itcast.oa.service.HelloWorld;
public class HelloWorldImpl2 implements HelloWorld {
public void printHelloWorld() {
System.out.println("Enter HelloWorldImpl2.printHelloWorld()");
}
public void doPrint() {
System.out.println("Enter HelloWorldImpl2.doPrint()");
return;
}
}
橫切關注點,這裡面是列印時間:
package cn.itcast.oa.service.impl;
public class TimeHandler {
public void printTime() {
System.out.println("CurrentTime = " + System.currentTimeMillis());
}
}
測試程式碼:
package cn.itcast.oa.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.oa.service.HelloWorld;
public class TestAop {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");
HelloWorld hw1 = (HelloWorld) ctx.getBean("helloWorldImpl1");
HelloWorld hw2 = (HelloWorld) ctx.getBean("helloWorldImpl2");
hw1.printHelloWorld();
System.out.println();
hw1.doPrint();
System.out.println();
hw2.printHelloWorld();
System.out.println();
hw2.doPrint();
}
}
新建aop.xml配置檔案,配置檔案內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="helloWorldImpl1" class="cn.itcast.oa.service.impl.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="cn.itcast.oa.service.impl.HelloWorldImpl2" />
<bean id="timeHandler" class="cn.itcast.oa.service.impl.TimeHandler" />
<aop:config>
<aop:aspect id="time" ref="timeHandler">
<aop:pointcut id="addAllMethod"
expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
</aop:config>
</beans>
實驗結果:
CurrentTime = 1482635730488
Enter HelloWorldImpl1.printHelloWorld()
CurrentTime = 1482635730489
CurrentTime = 1482635730491
Enter HelloWorldImpl1.doPrint()
CurrentTime = 1482635730491
CurrentTime = 1482635730491
Enter HelloWorldImpl2.printHelloWorld()
CurrentTime = 1482635730491
CurrentTime = 1482635730491
Enter HelloWorldImpl2.doPrint()
CurrentTime = 1482635730491
基於Spring的AOP使用其他細節
1、增加一個橫切關注點,列印日誌,Java類為:
package cn.itcast.oa.service.impl;
public class LogHandler {
public void LogBefore() {
System.out.println("Log before method");
}
public void LogAfter() {
System.out.println("Log after method");
}
}
aop.xml配置檔案內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="helloWorldImpl1" class="cn.itcast.oa.service.impl.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="cn.itcast.oa.service.impl.HelloWorldImpl2" />
<bean id="timeHandler" class="cn.itcast.oa.service.impl.TimeHandler" />
<bean id="logHandler" class="cn.itcast.oa.service.impl.LogHandler" />
<aop:config>
<aop:aspect id="time" ref="timeHandler">
<aop:pointcut id="addAllMethod"
expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
<aop:aspect id="log" ref="logHandler" order="2">
<aop:pointcut id="printLog"
expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />
<aop:before method="LogBefore" pointcut-ref="printLog" />
<aop:after method="LogAfter" pointcut-ref="printLog" />
</aop:aspect>
</aop:config>
</beans>
測試程式碼不變,測試結果如下:
Log before method
CurrentTime = 1482637050240
Enter HelloWorldImpl1.printHelloWorld()
CurrentTime = 1482637050241
Log after method
Log before method
CurrentTime = 1482637050244
Enter HelloWorldImpl1.doPrint()
CurrentTime = 1482637050244
Log after method
Log before method
CurrentTime = 1482637050244
Enter HelloWorldImpl2.printHelloWorld()
CurrentTime = 1482637050245
Log after method
Log before method
CurrentTime = 1482637050246
Enter HelloWorldImpl2.doPrint()
CurrentTime = 1482637050246
Log after method
要想讓logHandler在timeHandler前使用有兩個辦法:
(1)aspect裡面有一個order屬性,order屬性的數字就是橫切關注點的順序
(2)把logHandler定義在timeHandler前面,Spring預設以aspect的定義順序作為織入順序
2、我只想織入介面中的某些方法
修改一下pointcut的expression就好了:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<bean id="helloWorldImpl1" class="cn.itcast.oa.service.impl.HelloWorldImpl1" />
<bean id="helloWorldImpl2" class="cn.itcast.oa.service.impl.HelloWorldImpl2" />
<bean id="timeHandler" class="cn.itcast.oa.service.impl.TimeHandler" />
<bean id="logHandler" class="cn.itcast.oa.service.impl.LogHandler" />
<aop:config>
<aop:aspect id="time" ref="timeHandler">
<aop:pointcut id="addAllMethod"
expression="execution(* cn.itcast.oa.service.HelloWorld.*(..))" />
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
<aop:aspect id="log" ref="logHandler" order="2">
<aop:pointcut id="printLog"
expression="execution(* cn.itcast.oa.service.HelloWorld.do*(..))" />
<aop:before method="LogBefore" pointcut-ref="printLog" />
<aop:after method="LogAfter" pointcut-ref="printLog" />
</aop:aspect>
</aop:config>
</beans>
表示timeHandler只會織入HelloWorld介面print開頭的方法,logHandler只會織入HelloWorld介面do開頭的方法
3、強制使用CGLIB生成代理
前面說過Spring使用動態代理或是CGLIB生成代理是有規則的,高版本的Spring會自動選擇是使用動態代理還是CGLIB生成代理內容,當然我們也可以強制使用CGLIB生成代理,那就是裡面有一個”proxy-target-class”屬性,這個屬性值如果被設定為true,那麼基於類的代理將起作用,如果proxy-target-class被設定為false或者這個屬性被省略,那麼基於介面的代理將起作用
相關文章
- Spring aop練手Spring
- [Spring之AOP]Spring
- 死磕Spring之AOP篇 - Spring AOP總覽Spring
- Spring 3.0 AOP 之 AOP 術語 (一)Spring
- Spring之AOP實現Spring
- (002)Spring 之 AOPSpring
- Spring AOP學習筆記01:AOP概述Spring筆記
- Spring5.0原始碼學習系列之Spring AOP簡述Spring原始碼
- 死磕Spring之AOP篇 - Spring AOP常見面試題Spring面試題
- SSM框架學習之Spring的AOP學習以及資料整理SSM框架Spring
- 死磕Spring之AOP篇 - Spring AOP自動代理(一)入口Spring
- Spring Boot之IOC&AOPSpring Boot
- Spring框架系列之AOP思想Spring框架
- Spring AOP之原始碼分析Spring原始碼
- Spring AOP學習筆記02:如何開啟AOPSpring筆記
- Spring-boot整合AOP及AOP相關學習Springboot
- Spring AOP學習筆記03:AOP的核心實現之獲取增強器Spring筆記
- Spring核心系列之AOP(一)Spring
- Spring核心系列之AOP(二)Spring
- 死磕Spring之AOP篇 - Spring AOP註解驅動與XML配置SpringXML
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件
- Spring AOP學習筆記05:AOP失效的罪因Spring筆記
- Spring框架系列(10) - Spring AOP實現原理詳解之AOP代理的建立Spring框架
- Spring-AOP之工作實踐(二)Spring
- Spring之AOP面向切面程式設計Spring程式設計
- 死磕Spring之AOP篇 - Spring AOP兩種代理物件的攔截處理Spring物件
- Spring框架系列(9) - Spring AOP實現原理詳解之AOP切面的實現Spring框架
- Spring AOPSpring
- spring AOPSpring
- [Spring]AOPSpring
- Spring學習之——手寫Spring原始碼V2.0(實現IOC、DI、MVC、AOP)Spring原始碼MVC
- 死磕Spring之AOP篇 - Spring 事務詳解Spring
- 深入學習Spring框架(三)- AOP面向切面Spring框架
- Spring學習筆記五: AOP入門Spring筆記
- spring之AOP的概念及簡單案例Spring
- Spring系列之AOP基本主要類概述Spring
- 徹底征服 Spring AOP 之 理論篇Spring
- 死磕Spring之AOP篇 - Spring AOP自動代理(二)篩選合適的通知器Spring