AOP(Aspect Oriented Programming览闰,面向切面編程)院尔,通過提供另一種思考程序的方式來補(bǔ)充OOP(Object Oriented Programming推捐,面向?qū)ο缶幊蹋┦崆臁OP是橫向抽取贯吓,OOP是縱向抽象。
定義:在運行時弓柱,動態(tài)地將代碼切入到類的指定
方法
沟堡、指定位置的編程思想就是面向切面的編程疮鲫。主要應(yīng)用場景:收集日志、事務(wù)處理弦叶、安全檢測。
AOP 基本上是通過代理機(jī)制的實現(xiàn)
代理模式的例子
編寫 Move 接口
package com.spring.aop;
public interface Move {
void move();
}
編寫 Tank 類妇多,實現(xiàn) Move 接口
package com.spring.aop;
public class Tank implements Move {
@Override
public void move() {
System.out.println("Tank is moving!");
}
}
編寫 TankProxy 類
package com.spring.aop;
public class TankProxy implements Move{
private Move t;
public TankProxy (Move t) {
this.t = t;
}
@Override
public void move() {
System.out.println("start");
t.move();
System.out.println("stop");
}
}
運行
package com.spring.aop;
public class MoveApp {
public static void main(String[] args) {
Move t1 = new Tank();
Move moveProxy = new TankProxy(t1);
moveProxy.move();
}
}
注意:代理不能代理具體的類伤哺,只能代理接口。
理解AOP中的幾個概念
- Aspect(切面):將關(guān)注點進(jìn)行模塊化者祖。
- Join Point(連接點):在程序執(zhí)行過程中的某個特定的點,如謀方法調(diào)用時或處理異常時立莉。
- Advice(通知):在切面的某個特定的連接點上執(zhí)行的動作。
- PointCut(切入點):匹配連接點的斷言七问。
- Introduction(引入):聲明額外的方法或某個類型的字段蜓耻。
- Target Object(目標(biāo)對象):被一個或多個切面所通知的對象。
- AOP Proxy(AOP代理):AOP框架創(chuàng)建的對象,用來實現(xiàn) Aspect Contract 包括通知方法執(zhí)行等功能械巡。
- Weaving(織入):把切面連接到其他的應(yīng)用程序類型或?qū)ο笊?并創(chuàng)建一個 Advice 的對象刹淌。
其中,Advice 的主要類型有:
- Before Advice(前置通知)
- After Returning Advice(返回后通知)
- After Throwing Advice(拋出異常后通知)
- After (finally)Advice(最后通知)
- Around Advice(環(huán)繞通知)
切入點和連接點的匹配讥耗,是AOP的關(guān)鍵
Spring AOP
- Spring AOP 用純 Java 實現(xiàn)有勾,目前僅支持方法調(diào)用作為連接點。
- Spring AOP 通常和 Spring IoC 容器一起使用古程。
Hello 的前置增強(qiáng)練習(xí)
pom.xml 中添加 AOP 相關(guān)依賴
<!--spring-aop依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!--aspectj依賴-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
Hello 接口和實現(xiàn)類
package com.spring.aop;
public interface Hello {
String sayHello();
}
package com.spring.aop;
public class HelloImpl implements Hello {
@Override
public String sayHello() {
return "Spring AOP";
}
}
MyBefore 類
package com.spring.aop;
//用戶自定義前置增強(qiáng)類
public class MyBefore {
public void beforeMethod() {
System.out.println("This is a before method...");
}
}
配置文件
<bean id="hello" class="com.spring.aop.HelloImpl"/>
<bean id="myBefore" class="com.spring.aop.MyBefore"/>
<aop:config>
<aop:aspect id="before" ref="myBefore">
<aop:pointcut id="myPointcut" expression="execution(* com.spring.aop.*.*(..))"/>
<aop:before method="beforeMethod" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
應(yīng)用主類
package com.spring.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloApp {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = (Hello) ac.getBean("hello");
System.out.println(hello.sayHello());
}
}