面向切面
- 原理:AOP(Aspect Oriented Programming)在不增加代碼的基礎(chǔ)上增加新的功能夷野,將多種類要實(shí)現(xiàn)的公共功能抽象出來,形成自己的功能代碼拇泛。也可以說是將交叉的功能(切面)獨(dú)立出來滨巴,再交由需要該功能的類對(duì)象調(diào)用(織入)。
- 案例:調(diào)用函數(shù)記錄日志俺叭。
- 想法:
- 提取出公共功能恭取,形成類;
- 搭建起公共類與要調(diào)用類的橋熄守;
- 借助公共接口實(shí)現(xiàn)類間聯(lián)系蜈垮;
- 使用通知,進(jìn)行原過程點(diǎn)的攔截裕照;
- 引入代理ProxyFactoryBean攒发,幫助實(shí)現(xiàn)功能(織入)。
- 實(shí)現(xiàn):
- Spring提供了自己的規(guī)范晋南,通知類型為專有類型惠猿,分別為:
- 前置通知:進(jìn)入方法之前被調(diào)用。
- 后置通知:方法使用之后被調(diào)用负间。
- 環(huán)繞通知:方法前后均被調(diào)用偶妖。
- 異常通知:存在異常時(shí)被調(diào)用。
- 引入通知:
- 具體代碼:
寫入通知MyMethodBeforeAdvice.java
package com.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
//繼承前置通知接口
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
@Override
//參數(shù)含義:被調(diào)用等方法名唉擂,方法傳遞的參數(shù)餐屎,目標(biāo)對(duì)象
public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("記錄日志"+arg0.getName());
}
}
配置代理:
先建立公共接口ParentInterface.java
package com.aop;
public interface ParentInterface {
public void sayhello();
}
繼承類Testone.java
package com.aop;
public class Testone implements ParentInterface {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void sayhello() {
System.out.print("one hello"+name);
}
}
beans.xml
<!-- 要寫入注解對(duì)象 -->
<bean id="testone" class="com.aop.Testone">
<property name="name" value="小紅"></property>
</bean>
<!-- 前置通知對(duì)象 -->
<bean id="myMethodBeforeAdvice" class="com.aop.MyMethodBeforeAdvice" />
<!-- 代理對(duì)象 -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 引入接口,搭建橋梁 -->
<property name="proxyInterfaces">
<list>
<value>com.aop.ParentInterface</value>
</list>
</property>
<!-- 引入通知 -->
<property name="interceptorNames">
<list>
<value>myMethodBeforeAdvice</value>
</list>
</property>
<!-- 目標(biāo)對(duì)象-->
<property name="target" ref="testone" />
</bean>
測試代碼Test.java
package com.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("com/aop/beans.xml");
ParentInterface emp=(ParentInterface) ac.getBean("proxyFactoryBean");
//接口獲取玩祟,該過程完成通知織入
emp.sayhello();
//調(diào)用織入后的函數(shù)腹缩,完成目標(biāo)
}
}