AOP的两种实现方式
生活随笔
收集整理的這篇文章主要介紹了
AOP的两种实现方式
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
AOP,面向切面編程,可以通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一添加功能的一種技術(shù)。??
? Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容。利用AOP可以對業(yè)務(wù)邏輯的各個部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
? 有兩種方式可以實現(xiàn)aop,一種是根據(jù)利用jdk自帶的proxy,另外一種是利用cglib的proxy.
? 一 jdk代理
??? JDK的動態(tài)代理主要涉及到j(luò)ava.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中 InvocationHandler是一個接口,可以通過實現(xiàn)該接口定義橫切邏輯,在并通過反射機(jī)制調(diào)用目標(biāo)類的代碼,動態(tài)將橫切邏輯和業(yè)務(wù)邏輯編織在一起。
自定義一個接口
public interface TestInterface {
??? public void insert();
}
實現(xiàn)接口
public class TestImpl implements TestInterface{
??? @Override
??? public void insert() {
??? ??? // TODO Auto-generated method stub
??? ??? System.out.println("插入數(shù)據(jù)");
??? ????
??? }
}
創(chuàng)建jdk動態(tài)代理的工廠類
public class JdkDymanicProxyFactory implements InvocationHandler{
????
??? private Object targetObject;
??? public Object createProxyFactory(Object target){
??? ??? this.targetObject = target;
??? ??? return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
??? }
??? //執(zhí)行方法的時候回去回調(diào)這個函數(shù)
??? public Object invoke(Object proxy, Method method, Object[] args)
??? ??? ??? throws Throwable {
??? ??? // TODO Auto-generated method stub
??? ??? //在這里做一下日記
??? ??? System.out.println("execute:"+method.getName());
??? ??? return method.invoke(targetObject, args);
??? }
}
測試執(zhí)行結(jié)果
package com.lwq;
/**
?* @author thomaslwq?
?* @version 創(chuàng)建時間:Sep 17, 2012 8:56:20 AM
?* 類說明 利用jdk的動態(tài)代理實現(xiàn)aop
?*/
public class JdkProxyTest {
????
??? public static void main(String args[]){
??? ????
??? ??? JdkDymanicProxyFactory jdpf = new JdkDymanicProxyFactory();
??? ??? TestInterface ti = (TestInterface) jdpf.createProxyFactory(new TestImpl());
??? ??? ti.insert();
??? }
}
運行結(jié)果如下:
execute:insert
插入數(shù)據(jù)
二 利用cglib代理實現(xiàn)aop
CGlib是一個強(qiáng)大的,高性能,高質(zhì)量的Code生成類庫。它可以在運行期擴(kuò)展Java類與實現(xiàn)Java接口。? CGLIB是針對類實現(xiàn)代理的,主要對指定的類生成一個子類,并覆蓋其中的方法, 因為是繼承,所以不能使用final來修飾類或方法 。和jdk代理實現(xiàn)不同的是,cglib不要求類實現(xiàn)接口。
即你可以直接編出一個類:
public class CglibTestImpl {
??? public void insert() {
??? ??? // TODO Auto-generated method stub
??? ??? System.out.println("插入數(shù)據(jù)");
??? ????
??? }
}
然后創(chuàng)建cglib代理的工廠類:
package com.lwq;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
?* @author thomaslwq?
?* @version 創(chuàng)建時間:Sep 17, 2012 9:24:23 AM
?* 類說明
?*/
public class CglibProxyFactory implements MethodInterceptor{
????
??? private Object targetObject;
??? public Object createProxyInstance(Object target){
??? ??? this.targetObject = target;
??? ??? Enhancer enhancer = new Enhancer();
??? ??? enhancer.setSuperclass(this.targetObject.getClass());
??? ??? //設(shè)置回調(diào)函數(shù)
??? ??? enhancer.setCallback(this);
??? ??? return enhancer.create();
??? ????
??? }
??? @Override
??? public Object intercept(Object obj, Method method, Object[] args,
??? ??? ??? MethodProxy proxy) throws Throwable {
??? ??? // TODO Auto-generated method stub
??? ??? System.out.println("record:"+method.getName());
??? ??? System.out.println("Object:"+obj.getClass());
??? ??? System.out.println("targetObject:"+targetObject.getClass());
??? ??? return method.invoke(targetObject, args);
??? }
}
最后寫一個測試類:
package com.lwq;
/**
?* @author thomaslwq?
?* @version 創(chuàng)建時間:Sep 17, 2012 9:29:21 AM
?* 類說明
?*/
public class CglibProxyTest {
??? /**
??? ?* @param args
??? ?*/
??? public static void main(String[] args) {
??? ??? // TODO Auto-generated method stub
??? ??? CglibProxyFactory cpf = new CglibProxyFactory();
??? ??? //沒有實現(xiàn)接口
??? ??? CglibTestImpl ti = (CglibTestImpl)cpf.createProxyInstance(new CglibTestImpl());
??? ??? ti.insert();
??? }
}
測試結(jié)果如下:
record:insert
插入數(shù)據(jù)
JDK動態(tài)代理和CGLIB字節(jié)碼生成的區(qū)別??
* JDK動態(tài)代理只能對實現(xiàn)了接口的類生成代理,而不能針對類?
* CGLIB是針對類實現(xiàn)代理,主要是對指定的類生成一個子類,覆蓋其中的方法?
? 因為是繼承,所以該類或方法最好不要聲明成final?
? Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容。利用AOP可以對業(yè)務(wù)邏輯的各個部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
? 有兩種方式可以實現(xiàn)aop,一種是根據(jù)利用jdk自帶的proxy,另外一種是利用cglib的proxy.
? 一 jdk代理
??? JDK的動態(tài)代理主要涉及到j(luò)ava.lang.reflect包中的兩個類:Proxy和InvocationHandler。其中 InvocationHandler是一個接口,可以通過實現(xiàn)該接口定義橫切邏輯,在并通過反射機(jī)制調(diào)用目標(biāo)類的代碼,動態(tài)將橫切邏輯和業(yè)務(wù)邏輯編織在一起。
自定義一個接口
public interface TestInterface {
??? public void insert();
}
實現(xiàn)接口
public class TestImpl implements TestInterface{
??? @Override
??? public void insert() {
??? ??? // TODO Auto-generated method stub
??? ??? System.out.println("插入數(shù)據(jù)");
??? ????
??? }
}
創(chuàng)建jdk動態(tài)代理的工廠類
public class JdkDymanicProxyFactory implements InvocationHandler{
????
??? private Object targetObject;
??? public Object createProxyFactory(Object target){
??? ??? this.targetObject = target;
??? ??? return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
??? }
??? //執(zhí)行方法的時候回去回調(diào)這個函數(shù)
??? public Object invoke(Object proxy, Method method, Object[] args)
??? ??? ??? throws Throwable {
??? ??? // TODO Auto-generated method stub
??? ??? //在這里做一下日記
??? ??? System.out.println("execute:"+method.getName());
??? ??? return method.invoke(targetObject, args);
??? }
}
測試執(zhí)行結(jié)果
package com.lwq;
/**
?* @author thomaslwq?
?* @version 創(chuàng)建時間:Sep 17, 2012 8:56:20 AM
?* 類說明 利用jdk的動態(tài)代理實現(xiàn)aop
?*/
public class JdkProxyTest {
????
??? public static void main(String args[]){
??? ????
??? ??? JdkDymanicProxyFactory jdpf = new JdkDymanicProxyFactory();
??? ??? TestInterface ti = (TestInterface) jdpf.createProxyFactory(new TestImpl());
??? ??? ti.insert();
??? }
}
運行結(jié)果如下:
execute:insert
插入數(shù)據(jù)
二 利用cglib代理實現(xiàn)aop
CGlib是一個強(qiáng)大的,高性能,高質(zhì)量的Code生成類庫。它可以在運行期擴(kuò)展Java類與實現(xiàn)Java接口。? CGLIB是針對類實現(xiàn)代理的,主要對指定的類生成一個子類,并覆蓋其中的方法, 因為是繼承,所以不能使用final來修飾類或方法 。和jdk代理實現(xiàn)不同的是,cglib不要求類實現(xiàn)接口。
即你可以直接編出一個類:
public class CglibTestImpl {
??? public void insert() {
??? ??? // TODO Auto-generated method stub
??? ??? System.out.println("插入數(shù)據(jù)");
??? ????
??? }
}
然后創(chuàng)建cglib代理的工廠類:
package com.lwq;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
?* @author thomaslwq?
?* @version 創(chuàng)建時間:Sep 17, 2012 9:24:23 AM
?* 類說明
?*/
public class CglibProxyFactory implements MethodInterceptor{
????
??? private Object targetObject;
??? public Object createProxyInstance(Object target){
??? ??? this.targetObject = target;
??? ??? Enhancer enhancer = new Enhancer();
??? ??? enhancer.setSuperclass(this.targetObject.getClass());
??? ??? //設(shè)置回調(diào)函數(shù)
??? ??? enhancer.setCallback(this);
??? ??? return enhancer.create();
??? ????
??? }
??? @Override
??? public Object intercept(Object obj, Method method, Object[] args,
??? ??? ??? MethodProxy proxy) throws Throwable {
??? ??? // TODO Auto-generated method stub
??? ??? System.out.println("record:"+method.getName());
??? ??? System.out.println("Object:"+obj.getClass());
??? ??? System.out.println("targetObject:"+targetObject.getClass());
??? ??? return method.invoke(targetObject, args);
??? }
}
最后寫一個測試類:
package com.lwq;
/**
?* @author thomaslwq?
?* @version 創(chuàng)建時間:Sep 17, 2012 9:29:21 AM
?* 類說明
?*/
public class CglibProxyTest {
??? /**
??? ?* @param args
??? ?*/
??? public static void main(String[] args) {
??? ??? // TODO Auto-generated method stub
??? ??? CglibProxyFactory cpf = new CglibProxyFactory();
??? ??? //沒有實現(xiàn)接口
??? ??? CglibTestImpl ti = (CglibTestImpl)cpf.createProxyInstance(new CglibTestImpl());
??? ??? ti.insert();
??? }
}
測試結(jié)果如下:
record:insert
插入數(shù)據(jù)
JDK動態(tài)代理和CGLIB字節(jié)碼生成的區(qū)別??
* JDK動態(tài)代理只能對實現(xiàn)了接口的類生成代理,而不能針對類?
* CGLIB是針對類實現(xiàn)代理,主要是對指定的類生成一個子類,覆蓋其中的方法?
? 因為是繼承,所以該類或方法最好不要聲明成final?
總結(jié)
以上是生活随笔為你收集整理的AOP的两种实现方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 友情提醒:欲开发android5.0以上
- 下一篇: java使用动态代理来实现AOP(日志记