IOC和AOP是Spring的兩大基石,AOP(面向方面編程),也可稱為面向切面編程,是一種編程范式,提供從另一個角度來考慮程序結構從而完善面向對象編程(OOP)。
在進行 OOP 開發時,都是基於對組件(比如類)進行開發,然後對組件進行組合,OOP 最大問題就是無法解耦組件進行開發,比如我們上邊舉例,而 AOP 就是為了克服這個問題而出現的,它來進行這種耦合的分離。AOP 為開發者提供一種進行橫切關注點(比如日志關注點)分離並織入的機制,把橫切關注點分離,然後通過某種技術織入到系統中,從而無耦合的完成了我們的功能。
在 AOP 中,通過切入點選擇目標對象的連接點,然後在目標對象的相應連接點處織入通知,而切入點和通知就是切面(橫切關注點),而在目標對象連接點處應用切面的實現方式是通過 AOP 代理對象,如圖所示。
AOP代理就是 AOP框架通過代理模式創建的對象,Spring使用 JDK動態代理或 CGLIB代理來實現, Spring 缺省使用 JDK 動態代理來實現,從而任何接口都可被代理,如果被代理的對象實現不是接口將默認使用 CGLIB 代理,不過 CGLIB 代理當然也可應用到接口。AOP 代理的目的就是將切面織入到目標對象。
新建工程,導入Spring中對應的包,最後引入的jar包如下所示(有些包spring的lib下沒有,需要另外下載):
(1)定義目標接口
package com.log;
public interface IHelloWorldService {
public void sayHello();
}
(2)定義目標接口實現類
package com.log;
public class HelloWorldService implements IHelloWorldService {
@Override
public void sayHello() {
System.out.println("---hello world---");
}
}
(3)定義切面支持類
package com.log;
public class HelloWorldAspect {
public void beforeAdvice() {
System.out.println("---before advice---");
}
public void afterAdvice() {
System.out.println("---after advice---");
}
}
(4)在XML中進行配置
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 配置目標類 -->
<bean id="helloWorldService" class="com.log.HelloWorldService"/>
<!-- 配置切面 -->
<bean id="aspect" class="com.log.HelloWorldAspect"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.log..*.*(..))"/>
<!-- aop:aspect的ref引用切面支持類的方法 -->
<aop:aspect ref="aspect">
<aop:before pointcut-ref="pointcut"
method="beforeAdvice"/>
<aop:after pointcut-ref="pointcut"
method="afterAdvice"/>
</aop:aspect>
</aop:config>
</beans>
切入點使用<aop:config>標簽下的<aop:pointcut>配置, expression屬性用於定義切入點模式,默認是AspectJ語法,“ execution(* cn.javass..*.*(..))”表示匹配cn.javass包及子包下的任何方法執行。關於expression屬性如何配置請點擊:expression配置 http://www.linuxidc.com/Linux/2016-06/132196.htm
切面使用<aop:config>標簽下的<aop:aspect>標簽配置,其中“ ref”用來引用切面支持類的方法。
前置通知使用<aop:aspect>標簽下的<aop:before>標簽來定義, pointcut-ref屬性用於引用切入點Bean, 而method用來引用切面通知實現類中的方法,該方法就是通知實現,即在目標類方法執行之前調用的方法。
最終通知使用<aop:aspect>標簽下的<aop:after >標簽來定義,切入點除了使用pointcut-ref屬性來引用已經存在的切入點,也可以使用pointcut屬性來定義,如pointcut="execution(* cn.javass..*.*(..))", method屬性同樣是指定通知實現,即在目標類方法執行之後調用的方法。
(5)測試運行
package com.log;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aopBean.xml");
IHelloWorldService hello = context.getBean("helloWorldService", IHelloWorldService.class);
hello.sayHello();
HelloWorldAspect advice = context.getBean("aspect", HelloWorldAspect.class);
advice.beforeAdvice();
}
}
(6)輸出結果
Spring中如何配置Hibernate事務 http://www.linuxidc.com/Linux/2013-12/93681.htm
Struts2整合Spring方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm
基於 Spring 設計並實現 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm
Spring-3.2.4 + Quartz-2.2.0集成實例 http://www.linuxidc.com/Linux/2013-10/91524.htm
使用 Spring 進行單元測試 http://www.linuxidc.com/Linux/2013-09/89913.htm
運用Spring注解實現Netty服務器端UDP應用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm
Spring 3.x 企業應用開發實戰 PDF完整高清掃描版+源代碼 http://www.linuxidc.com/Linux/2013-10/91357.htm
Spring 的詳細介紹:請點這裡
Spring 的下載地址:請點這裡