最詳細的代理講解--JDK動態代理和cglib代理
1.代理相關的概念
代理模式
代理模式的英文叫做Proxy或Surrogate,中文都可譯為”代理“,所謂代理,就是一個人或者一個機構代表另一個人或者另一個機構採取行動。在一些情況下,一個客戶不想或者不能夠直接引用一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用
抽象主題角色
宣告瞭真實主題和代理主題的共同介面,這樣一來在任何可以使用真實主題的地方都可以是使用代理主題
代理主題(Proxy)角色
代理主題角色內部含有對真實主題的引用,從而可以在任何時候操作真實主題物件;代理主題角色提供一個與真實主題角色相同的介面,以便可以在任何時候都可以替代真實主題控制對真實主題的引用,負責在需要的時候建立真實主題物件(和刪除真實主題物件);代理角色通常在將客戶端呼叫傳遞給真實的主題之前或之後,都要執行某個操作,而不是單純地將呼叫傳遞給真實主題物件。
真實主題角色
定義了代理角色所代表地真實物件
spring有兩種代理方式:
1.若目標物件實現了若干介面,spring使用JDK的java.lang.reflect.Proxy類代理。
2.若目標物件沒有實現任何介面,spring使用CGLIB庫生成目標物件的子類。
2.案例分析兩種代理的異同
JDK動態代理
注意事項:編寫JDK代理類引用的是java的工具包lang中的反射包下的Proxy,不需要引入其他jar包,但是要注意不要倒錯包了;import java.lang.reflect.Proxy; 目標物件實現了若干介面。
兩個介面類SayByeBye、SayGoodBye
package www.csdn.spring.proxy.jdk;
public interface SayByeBye {
public void sayByeBye();
}
package www.csdn.spring.proxy.jdk;
public interface SayGoodBye {
public void sayGoodBye(String content);
}
這兩個介面類的實現類SayByeImplement
package www.csdn.spring.proxy.jdk;
public class SayByeImpl implements SayGoodBye,SayByeBye {
@Override
public void sayGoodBye(String content) {
System.out.println("say:"+content);
}
@Override
public void sayByeBye() {
System.out.println("say:拜拜!");
}
}
JDK代理類JDKProxy
package www.csdn.spring.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler {
// 代理目標物件
private Object target;
// 建立目標物件的代理物件
public Object createProxyInstance(Object target) {
// 代理的目標物件
this.target = target;
// 建立代理物件
// 1、定義代理類的類載入器
// 2、代理類要實現的介面列表
// 3、 指派方法呼叫的呼叫處理程式
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
/**
* proxy:目標物件的代理例項,改代理例項不管執行多少次都是class $Proxy4 ;
* method:對於代理例項呼叫介面方法的Method例項;
* args:方法引數
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/*
* 測試invoke方法的三個引數的含義
*/
System.out.println("proxy:"+proxy.getClass());
System.out.println("method:"+method.getName());
if(args!=null&&args.length>0){
for(Object obj : args){
System.out.println("args:"+obj);
}
}
//宣告返回值
Object returnValue = null;
beforeMethod();
returnValue = method.invoke(target, args);
afterMethod();
return returnValue;
}
public void beforeMethod(){
System.out.println("----方法執行之前的操作----");
}
public void afterMethod(){
System.out.println("----方法執行之後的操作----");
}
}
測試類ProTest
package www.csdn.spring.proxy.jdk;
import org.junit.Test;
public class ProxyTest {
@Test
public void testSay() {
//真是主題角色
SayByeImpl sayByeImpl = new SayByeImpl();
/*
* //不使用代理的情況
* sayByeImpl.sayGoodBye("我要離婚!");
* sayByeImpl.sayByeBye();
*/
//代理主題角色,這裡用代理主題和真實主題實現的同樣介面類來接收建立的代理主題,就是建立一個目標類
SayGoodBye sayGoodBye = (SayGoodBye) new JDKProxy().createProxyInstance(sayByeImpl);
SayByeBye sayByeBye = (SayByeBye) new JDKProxy().createProxyInstance(sayByeImpl);
sayGoodBye.sayGoodBye("受不了了,我要離婚!");
System.out.println("00000000000000000000000000000000000000000000000");
sayByeBye.sayByeBye();
}
}
CGLIB做代理
CGlib是一個強大的,高效能,高質量的Code生成類庫。它可以在執行期擴充套件Java類與實現Java介面。
注意事項:使用cglib做代理,java中不想jdk動態代理那樣給封裝好了相應的類,他需要匯入所依賴的jar包asm-3.3.jar、cglib-2.2.jar這兩個jar包;目標物件沒有實現任何介面
目標類SayHello
package www.csdn.spring.proxy.cglib;
publicclass SayHello {
publicvoid say(String content) {
System.out.println("say:" + content);
}
}
cglib代理類CglibProxy
package www.csdn.spring.proxy.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor{
private Object target;
public Object createProxyInstance(Object target){
this.target = target;
//生成代理物件
Enhancer enhancer = new Enhancer();
// 用於設定代理物件的父類
enhancer.setSuperclass(this.target.getClass());
//設定回撥
enhancer.setCallback(this);
//建立代理物件
return enhancer.create();
}
/**
* proxy:目標物件代理的例項;
* method:目標物件呼叫父類方法的method例項 ;
* args:呼叫父類方法傳遞引數
* methodProxy:代理的方法去呼叫目標方法
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
/*
* 測試invoke方法的四個引數的含義
*/
System.out.println("proxy:"+proxy.getClass());
System.out.println("method:"+method.getName());
System.out.println("methodProxy:"+methodProxy.getSuperName());
if(args!=null&&args.length>0){
for(Object obj : args){
System.out.println("args:"+obj);
}
}
//宣告返回值
Object returnValue = null;
beforeMethod();
//使用method和methodProxy引數都可以呼叫invoke方法,並且執行出來的效果一樣
//returnValue = methodProxy.invoke(target, args);
returnValue = method.invoke(target, args);
afterMethod();
return returnValue;
}
public void beforeMethod(){
System.out.println("----方法執行之前的操作----");
}
public void afterMethod(){
System.out.println("----方法執行之後的操作----");
}
}
測試類proxyTest
package www.csdn.spring.proxy.cglib;
import org.junit.Test;
public class ProxyTest {
@Test
public void testSay() {
//真是主題角色
SayHello sayHello = new SayHello();
//sayHello.say("嗨!你好啊!");
//建立了一個 目標類的物件 ,jdk動態代理中建立的是介面類物件,cglib由於不實現任何介面,所以直接建立一個目標類的物件
SayHello sh = (SayHello) new CglibProxy().createProxyInstance(sayHello);
sh.say("嗨!你好啊!");
}
}
相關文章
- 靜態代理和動態代理(jdk/cglib)詳解JDKCGLib
- 代理模式詳解:靜態代理、JDK動態代理與Cglib動態代理模式JDKCGLib
- JDK動態代理和 CGLIB 代理JDKCGLib
- JDK動態代理和CGLib代理JDKCGLib
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- Java JDK Proxy和CGLib動態代理示例講解JavaJDKCGLib
- Java動態代理(JDK和cglib)JavaJDKCGLib
- spring aop原理 JDK動態代理和CGLIB動態代理SpringJDKCGLib
- 你必須會的 JDK 動態代理和 CGLIB 動態代理JDKCGLib
- cglib動態代理和jdk動態代理的區別與應用CGLibJDK
- 動態代理jdk和cglib的區別JDKCGLib
- JDK動態代理詳解JDK
- Jdk代理和CGLIB代理的區別JDKCGLib
- Java進階之 JDK動態代理與Cglib動態代理JavaJDKCGLib
- Spring動態代理的生成-如何判斷是使用JDK動態代理還是CGlib代理SpringJDKCGLib
- Spring原始碼剖析5:JDK和cglib動態代理原理詳解Spring原始碼JDKCGLib
- JDK 和 CGLib 實現動態代理和區別JDKCGLib
- 3.靜態代理&動態代理&CGlibCGLib
- CGLib 動態代理CGLib
- (轉)Java動態代理與CGLib代理JavaCGLib
- Java動態代理 jdk和cglib的實現比較JavaJDKCGLib
- 【4】JDK和CGLIB生成動態代理類的區別JDKCGLib
- 動態代理-cglib分析CGLib
- 動態代理jdk的Proxy與spring的CGlibJDKSpringCGLib
- 面試造火箭系列,栽在了cglib和jdk動態代理面試CGLibJDK
- JDK動態代理JDK
- SpringAOP中JDK和CGLib動態代理哪個更快?SpringJDKCGLib
- Java提高班(六)反射和動態代理(JDK Proxy和Cglib)Java反射JDKCGLib
- CGlib動態代理複習CGLib
- Jmh測試JDK,CGLIB,JAVASSIST動態代理方式的效能JDKCGLibJava
- JDK動態代理初探JDK
- 細說JDK動態代理的實現原理JDK
- 靜態代理和動態代理
- jdk的動態代理和靜態代理你還寫不出來嘛???JDK
- 深入理解靜態代理與JDK動態代理JDK
- jdk proxy invocationhandler (jdk動態代理)JDK
- 聊聊cglib動態代理遇到的坑CGLib
- java靜態代理和動態代理Java