動態代理
① java動態代理和cglib動態代理的區別
1、Jdk動態代理實例:復JDK動態代制理只能代理實現了介面的類,其他普通類不能實現。代理類會在newProxyInstance方法中生成
2、cglib動態代理:cglib是針對類實現代理的,為代理的類生成一個子類,覆蓋方法實現增強,因為採用的是繼承所以不能代理final修飾的類。需要cglib和asm兩個jar包
② java反射和動態代理有什麼關系
當然有了,發射是Java的最重要的底層知識。而動態代理其實質就是依靠反射來實現的。
③ Java 幾種動態代理實現及其性能比較
1. 動態代理是指在運行時,動態生成代理類。代理類的位元組碼將在運行時生成並載入當前的ClassLoader.
生成動態代理類的方法很多,如JDK自帶的動態代理、CGLIB、Javassist或者ASM庫。
JDK動態代理使用簡單,它內置在JDK中,因此不需要引入第三方Jar包,但相對功能比較弱。CGLIB和Javassist都是高級的位元組碼生成庫,總體性能比JDK自帶的動態代理好,而且功能十分強大。ASM是低級的位元組碼生成工具,使用ASM已經近乎在於使用Javabytecode編程,對開發人員要求較高,也是性能最好的一種動態代理生辰工具。但ASM的使用是在過於繁瑣,而且性能也沒有數量級的提升,與CGLIB等高級位元組碼生成工具相比,ASM程序的可維護性也較差。
JDK實現
1、步驟
1)通過實現InvocationHandler介面創建自己的調用處理器
2)通過為Proxy類指定ClassLoader對象和一組interface來創建動態代理類
3)通過反射機制獲得動態代理類的構造函數,其唯一參數類型是調用處理器介面類型
4)通過構造函數創建動態代理類實例,構造時調用處理器對象作為參數被傳入
2、創建代理
//InvocationHandlerImpl 實現了InvocationHandler介面,並能實現方法調用從代理類到委託類的分派轉發
//其內部通常包含指向委託類實例的引用,用於真正執行分派轉發過來的方法調用
InvocationHandler handler = new InvocaitonHandlerImpl(..);
//通過Proxy為包括Interface介面在內的一組介面動態創建代理類的對象
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{Interface.class,...});
//通過反射從生成的類對象獲得構造函數對象
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
//通過構造函數對象創建動態代理類實例
Interface Proxy = (Interface)constructor.newInstance(new Object[]{handler});
//Proxy類的靜態方法newProxyInstance對上面具體步驟的後三步做了封裝,簡化了動態代理對象的獲取過程。
//InvocationHandlerImpl實現了InvocaitonHandler介面,並能實現方法調用從代理類到委託類的分派轉發
InvocaitonHandler handler = new InvocationHandlerImpl(..);
//通過Proxy直接創建動態代理類實例
nterface proxy = (Interface)Proxy.newProxyInstance(classLoader,new Class[]{Interface.class},handler);
3、代碼
/**
* 介面
*
*/
public interface IDBQuery {
String request();
}
/**
* 真實的實現類,具體的目標對象
*
*/
public class DBQuery implements IDBQuery {
public DBQuery(){
try {
Thread.sleep(1000); //可能包含資料庫連接等耗時操作
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String request() {
return "request string";
}
}
/**
* JDK動態代理的實現類
*
*/
public class JdkDbQueryHandler implements InvocationHandler{
IDBQuery real = null; //主題介面
/**
* 生成Handler
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(real == null)
real = new DBQuery(); //如果是第一次調用,則生成真實對象
return real.request(); //使用真實主題完成實際的操作
}
/**
* 利用Handler生成動態代理對象
*/
public static IDBQuery createJdkProxy(){
//根據指定的類載入器和介面以及截獲器,返回代理類的一個實例對象
//ClassLoader loader :指定被代理對象的類載入器
//Class[] Interfaces :指定被代理對象所以事項的介面
//InvocationHandler h :指定需要調用的InvocationHandler對象
IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IDBQuery.class}, new JdkDbQueryHandler());
return jdkProxy;
}
}
④ java 動態代理怎麼理解
JAVA的靜態代理與動態代理比較
一、概念
代理模式是常用的Java 設計模式,它的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理消息、過濾消息、把消息轉發給委託類,以及事後處理消息等。代理類與委託類之間通常會存在關聯關系,一個代理類的對象與一個委託類的對象關聯,代理類的對象本身並不真正實現服務,而是通過調用委託類的對象的相關方法,來提供特定的服務。按照代理類的創建時期,代理類可分為兩種。
靜態代理類:
由程序員創建或由特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。動態代理類:在程序運行時,運用反射機制動態創建而成。
二、靜態代理類
如下, HelloServiceProxy 類是代理類,HelloServiceImpl類是委託類,這兩個類都實現了HelloService介面。其中HelloServiceImpl類是HelloService介面的真正實現者,而HelloServiceProxy類是通過調用HelloServiceImpl 類的相關方法來提供特定服務的。HelloServiceProxy類的echo()方法和getTime()方法會分別調用被代理的HelloServiceImpl 對象的echo()方法和getTime()方法,並且在方法調用前後都會執行一些簡單的列印操作。
由此可見,代理類可以為委託類預處理消息、把消息轉發給委託類和事後處理消息等。
常式1 HelloService.java
package proxy;
import java.util.Date;
public interface HelloService{
public String echo(String msg);
public Date getTime();
}
常式2 HelloServiceImpl.java
package proxy;
import java.util.Date;
public class HelloServiceImpl implements HelloService{
public String echo(String msg){
return "echo:"+msg;
}
public Date getTime(){
return new Date();
}
}
常式3 HelloServiceProxy.java
package proxy;
import java.util.Date;
public class HelloServiceProxy implements HelloService{
private HelloService helloService; //表示被代理的HelloService 實例
public HelloServiceProxy(HelloService helloService){
this.helloService=helloService;
}
public void setHelloServiceProxy(HelloService helloService){
this.helloService=helloService;
}
public String echo(String msg){
System.out.println("before calling echo()"); //預處理
String result=helloService.echo(msg); //調用被代理的HelloService 實例的echo()方法
System.out.println("after calling echo()"); //事後處理
return result;
}
public Date getTime(){
System.out.println("before calling getTime()"); //預處理
Date date=helloService.getTime(); //調用被代理的HelloService 實例的getTime()方法
System.out.println("after calling getTime()"); //事後處理
return date;
}
}
在Client1 類的main()方法中,先創建了一個HelloServiceImpl對象,又創建了一個HelloServiceProxy對象,最後調用HelloServiceProxy對象的echo()方法。
常式4 Client1.java
package proxy;
public class Client1{
public static void main(String args[]){
HelloService helloService=new HelloServiceImpl();
HelloService helloServiceProxy=new HelloServiceProxy(helloService);
System.out.println(helloServiceProxy.echo("hello"));
}
}
運行Client1 類,列印結果如下:
before calling echo()
after calling echo()
echo:hello
常式3 的HelloServiceProxy 類的源代碼是由程序員編寫的,在程序運行前,它的.class文件就已經存在了,這種代理類稱為靜態代理類。
三、動態代理類
與靜態代理類對照的是動態代理類,動態代理類的位元組碼在程序運行時由Java反射機制動態生成,無需程序員手工編寫它的源代碼。動態代理類不僅簡化了編程工作,而且提高了軟體系統的可擴展性,因為Java 反射機制可以生成任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 介面提供了生成動態代理類的能力。
Proxy類提供了創建動態代理類及其實例的靜態方法。
(1)getProxyClass()靜態方法負責創建動態代理類,它的完整定義如下:
public static Class getProxyClass(ClassLoader loader, Class[] interfaces) throws IllegalArgumentException
參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面。
(2)newProxyInstance()靜態方法負責創建動態代理類的實例,它的完整定義如下:
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler handler) throws
IllegalArgumentException
參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面,參數handler 指定與動態代理類關聯的 InvocationHandler 對象。
以下兩種方式都創建了實現Foo介面的動態代理類的實例:
/**** 方式一 ****/
//創建InvocationHandler對象
InvocationHandler handler = new MyInvocationHandler(...);
//創建動態代理類
Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });
//創建動態代理類的實例
Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
/**** 方式二 ****/
//創建InvocationHandler對象
InvocationHandler handler = new MyInvocationHandler(...);
//直接創建動態代理類的實例
Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler);
由Proxy類的靜態方法創建的動態代理類具有以下特點:
動態代理類是public、final和非抽象類型的;
動態代理類繼承了java.lang.reflect.Proxy類;
動態代理類的名字以「$Proxy」開頭;
動態代理類實現getProxyClass()和newProxyInstance()方法中參數interfaces指定的所有介面;
Proxy 類的isProxyClass(Class cl)靜態方法可用來判斷參數指定的類是否為動態代理類。只有通過Proxy類創建的類才是動態代理類;
動態代理類都具有一個public 類型的構造方法,該構造方法有一個InvocationHandler 類型的參數。
由Proxy類的靜態方法創建的動態代理類的實例具有以下特點:
1. 假定變數foo 是一個動態代理類的實例,並且這個動態代理類實現了Foo 介面,那麼「foo instanceof Foo」的值為true。把變數foo強制轉換為Foo類型是合法的:
(Foo) foo //合法
2.每個動態代理類實例都和一個InvocationHandler 實例關聯。Proxy 類的getInvocationHandler(Object proxy)靜態方法返回與參數proxy指定的代理類實例所關聯的InvocationHandler 對象。
3.假定Foo介面有一個amethod()方法,那麼當程序調用動態代理類實例foo的amethod()方法時,該方法會調用與它關聯的InvocationHandler 對象的invoke()方法。
InvocationHandler 介面為方法調用介面,它聲明了負責調用任意一個方法的invoke()方法:
Object invoke(Object proxy,Method method,Object[] args) throws Throwable
參數proxy指定動態代理類實例,參數method指定被調用的方法,參數args 指定向被調用方法傳遞的參數,invoke()方法的返回值表示被調用方法的返回值。
四、最後看一個實例:
HelloServiceProxyFactory 類的getHelloServiceProxy()靜態方法負責創建實現了HelloService介面的動態代理類的實例。
常式5 HelloServiceProxyFactory.java
package proxy;
import java.lang.reflect.*;
public class HelloServiceProxyFactory {
/** 創建一個實現了HelloService 介面的動態代理類的實例
* 參數helloService 引用被代理的HelloService 實例
*/
public static HelloService getHelloServiceProxy(final HelloService helloService){
//創建一個實現了InvocationHandler介面的匿名類的實例
InvocationHandler handler=new InvocationHandler(){
public Object invoke(Object proxy,Method method,Object args[])throws Exception{
System.out.println("before calling "+method); //預處理
Object result=method.invoke(helloService,args);
//調用被代理的HelloService 實例的方法
System.out.println("after calling "+method); //事後處理
return result;
}
};
Class classType=HelloService.class;
return (HelloService)Proxy.newProxyInstance(classType.getClassLoader(),
new Class[]{classType},
handler);
}
}
如下所示的Client2 類先創建了一個HelloServiceImpl 實例,然後創建了一個動態代理類實例helloServiceProxy,最後調用動態代理類實例的echo()方法。
常式6 Client2.java
package proxy;
public class Client2{
public static void main(String args[]){
HelloService helloService=new HelloServiceImpl();
HelloService helloServiceProxy=HelloServiceProxyFactory.getHelloServiceProxy(helloService);
System.out.println("動態代理類的名字為"+helloServiceProxy.getClass().getName());
System.out.println(helloServiceProxy.echo("Hello"));
}
}
運行Client2,列印結果如下:
動態代理類的名字為$Proxy0
before calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String)
after calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String)
echo:Hello
從結果看出,動態代理類的名字為$Proxy0。
PostScript
⑤ 如何獲得Java動態代理的代理類
AOP的攔截功能是由java中的動態代理來實現的。說白了,就是在目標類的基礎上增加切面邏輯,生成增強的目標類(該切面邏輯或者在目標類函數執行之前,或者目標類函數執行之後,或者在目標類函數拋出異常時候執行。不同的切入時機對應不同的Interceptor的種類,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。
那麼動態代理是如何實現將切面邏輯(advise)織入到目標類方法中去的呢?下面我們就來詳細介紹並實現AOP中用到的兩種動態代理。
AOP的源碼中用到了兩種動態代理來實現攔截切入功能:jdk動態代理和cglib動態代理。兩種方法同時存在,各有優劣。jdk動態代理是由Java內部的反射機制來實現的,cglib動態代理底層則是藉助asm來實現的。總的來說,反射機制在生成類的過程中比較高效,而asm在生成類之後的相關執行過程中比較高效(可以通過將asm生成的類進行緩存,這樣解決asm生成類過程低效問題)。還有一點必須注意:jdk動態代理的應用前提,必須是目標類基於統一的介面。如果沒有上述前提,jdk動態代理不能應用。由此可以看出,jdk動態代理有一定的局限性,cglib這種第三方類庫實現的動態代理應用更加廣泛,且在效率上更有優勢。。
1、定義介面和實現
[java] view plain print?
package com.meituan.hyt.test3.service;
public interface UserService {
public String getName(int id);
public Integer getAge(int id);
}
[java] view plain print?
package com.meituan.hyt.test3.service.impl;
import com.meituan.hyt.test3.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public String getName(int id) {
System.out.println("------getName------");
return "Tom";
}
@Override
public Integer getAge(int id) {
System.out.println("------getAge------");
return 10;
}
}
2、jdk動態代理實現
[java] view plain print?
package com.meituan.hyt.test3.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
if("getName".equals(method.getName())){
System.out.println("++++++before " + method.getName() + "++++++");
Object result = method.invoke(target, args);
System.out.println("++++++after " + method.getName() + "++++++");
return result;
}else{
Object result = method.invoke(target, args);
return result;
}
}
}
[java] view plain print?
package com.meituan.hyt.test3.jdk;
import com.meituan.hyt.test3.service.UserService;
import com.meituan.hyt.test3.service.impl.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Main1 {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
InvocationHandler invocationHandler = new MyInvocationHandler(userService);
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invocationHandler);
System.out.println(userServiceProxy.getName(1));
System.out.println(userServiceProxy.getAge(1));
}
}
運行結果
++++++before getName++++++
------getName------
++++++after getName++++++
Tom
------getAge------
10
3、cglib動態代理實現
Cglib是一個優秀的動態代理框架,它的底層使用ASM在內存中動態的生成被代理類的子類,使用CGLIB即使代理類沒有實現任何介面也可以實現動態代理功能。CGLIB具有簡單易用,它的運行速度要遠遠快於JDK的Proxy動態代理:
CGLIB的核心類:
net.sf.cglib.proxy.Enhancer – 主要的增強類
net.sf.cglib.proxy.MethodInterceptor – 主要的方法攔截類,它是Callback介面的子介面,需要用戶實現
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method類的代理類,可以方便的實現對源對象方法的調用,如使用:
Object o = methodProxy.invokeSuper(proxy, args);//雖然第一個參數是被代理對象,也不會出現死循環的問題。
net.sf.cglib.proxy.MethodInterceptor介面是最通用的回調(callback)類型,它經常被基於代理的AOP用來實現攔截(intercept)方法的調用。這個介面只定義了一個方法
public Object intercept(Object object, java.lang.reflect.Method method,
Object[] args, MethodProxy proxy) throws Throwable;
第一個參數是代理對像,第二和第三個參數分別是攔截的方法和方法的參數。原來的方法可能通過使用java.lang.reflect.Method對象的一般反射調用,或者使用 net.sf.cglib.proxy.MethodProxy對象調用。net.sf.cglib.proxy.MethodProxy通常被首選使用,因為它更快。
[java] view plain print?
package com.meituan.hyt.test3.cglib;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
System.out.println(method.getName());
Object o1 = methodProxy.invokeSuper(o, args);
System.out.println("++++++before " + methodProxy.getSuperName() + "++++++");
return o1;
}
}
[java] view plain print?
package com.meituan.hyt.test3.cglib;
import com.meituan.hyt.test3.service.UserService;
import com.meituan.hyt.test3.service.impl.UserServiceImpl;
import net.sf.cglib.proxy.Enhancer;
public class Main2 {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(cglibProxy);
UserService o = (UserService)enhancer.create();
o.getName(1);
o.getAge(1);
}
}
運行結果:
++++++before CGLIB$getName$0++++++
getName
------getName------
++++++before CGLIB$getName$0++++++
++++++before CGLIB$getAge$1++++++
getAge
------getAge------
++++++before CGLIB$getAge$1++++++
⑥ Java中的動態代理相對於靜態代理有何優點
缺Java中的動態代理相對於靜態代理優點:
1、靜態代理類和委託類實現了相同的介面,代理類通過委託類實現了相同的方法。這樣就出現了大量的代碼重復。如果介面增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了代碼維護的復雜度。
2、靜態代理對象只服務於一種類型的對象,如果要服務多類型的對象。勢必要為每一種對象都進行代理,靜態代理在程序規模稍大時就無法勝任了。如上的代碼是只為UserManager類的訪問提供了代理,但是如果還要為其他類如Department類提供代理的話,就需要我們再次添加代理Department的代理類。
⑦ spring中aop的動態代理機制有哪些
1.事務管理: (1)資料庫事務:(2)編程事務(3)聲明事物:Spring AOP-->聲明事物
2.日誌處理:
3.安全驗證: Spring AOP---OOP升級
靜態代理原理:目標對象:調用業務邏輯 代理對象:日誌管理
表示層調用--->代理對象(日誌管理)-->調用目標對象
動態代理原理:spring AOP採用動態代理來實現
(1)實現InvocationHandler介面
(2)創建代理類(通過java API)
⑧ spring的動態代理有幾種實現方式
JAVA 代理實現
代理的實現分動態代理和靜態代理,靜態代理的實現是對已經生成了的JAVA類進行封裝。
動態代理則是在運行時生成了相關代理累,在JAVA中生成動態代理一般有兩種方式。
JDK自帶實現方法
JDK實現代理生成,是用類 java.lang.reflect.Proxy, 實現方式如下
EX:
publicclassJDKProxy{
(finalObjectc){
returnProxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(),//JDK實現動態代理,但JDK實現必須需要介面
newInvocationHandler(){
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
//TODOAuto-generatedmethodstub
ObjectreObj=null;
System.out.print("yousay:");
reObj=method.invoke(c,args);
System.out.println("["+Calendar.getInstance().get(Calendar.HOUR)+":"
+Calendar.getInstance().get(Calendar.MINUTE)+""
+Calendar.getInstance().get(Calendar.SECOND)+"]");
returnreObj;
}
});
}
}
測試代理類方法
publicclassTestForPoxy{
publicstaticvoidmain(String[]args){
ServiceTestservice=newServiceTestImpl();
System.out.println(service.getClass().getSimpleName());
ServiceTestpoxyService=(ServiceTest)JDKProxy.getPoxyObject(service);
System.out.println(poxyService.getClass().getSuperclass());
poxyService.saySomething("hello,MyQQcodeis107966750.");
poxyService.saySomething("what'syourname?");
poxyService.saySomething("onlyfortest,hehe.");
}
}
1, Proxy實現代理的目標類必須有實現介面
2, 生成出來的代理類為介面實現類,和目標類不能進行轉換,只能轉為介面實現類進行調用
明顯特點:通過此方法生成出來的類名叫做 $Proxy0
用CGLIB包實現
CGLIB是一個開源項目,官方網址是:http://cglib.sourceforge.net/,可以去上面下載最新JAR包,
本項目用的是cglib-3.0.jar
本項目還加入了依賴JAR包asm-4.0.jar,asm-util-4.0.jar
實現方式如下
EX:
publicclassCGLIBProxy{
(Objectc){
Enhancerenhancer=newEnhancer();
enhancer.setSuperclass(c.getClass());
enhancer.setCallback(newMethodInterceptor(){
publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyproxy)throwsThrowable{
System.out.print("yousay:");
proxy.invokeSuper(arg0,arg2);
System.out.println("["+Calendar.getInstance().get(Calendar.HOUR)+":"
+Calendar.getInstance().get(Calendar.MINUTE)+""+Calendar.getInstance().get(Calendar.SECOND)
+"]");
returnnull;
}
});
returnenhancer.create();
}
}
測試代理類方法
publicclassTestForPoxy{
publicstaticvoidmain(String[]args){
ServiceTestservice=newServiceTestImpl();
System.out.println(service.getClass().getSimpleName());
//ServiceTestpoxyService=(ServiceTest)JDKProxy.getPoxyObject(service);
ServiceTestpoxyService=(ServiceTest)CGLIBProxy.getPoxyObject(service);
System.out.println(poxyService.getClass().getSuperclass());
poxyService.saySomething("hello,MyQQcodeis107966750.");
poxyService.saySomething("what'syourname?");
poxyService.saySomething("onlyfortest,hehe.");
}
}
1, CGLIB實現方式是對代理的目標類進行繼承
2, 生成出了的代理類可以沒方法,生成出來的類可以直接轉換成目標類或目標類實現介面的實現類,因JAVA向上轉換
明顯特點:通過輸出看出,看出生成出的代理類的parent類為代理的目標類
⑨ jdk動態代理與cglib動態代理有什麼區別
1.JDK動態代理
此時代理對象和目標對象實現了相同的介面,目標對象作為代理對象的一個屬性,具體介面實現中,可以在調用目標對象相應方法前後加上其他業務處理邏輯。
代理模式在實際使用時需要指定具體的目標對象,如果為每個類都添加一個代理類的話,會導致類很多,同時如果不知道具體類的話,怎樣實現代理模式呢?這就引出動態代理。
JDK動態代理只能針對實現了介面的類生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的所有方法,所以該類或方法不能聲明稱final的。
如果目標對象沒有實現介面,則默認會採用CGLIB代理;
如果目標對象實現了介面,可以強制使用CGLIB實現代理(添加CGLIB庫,並在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。
AOP包括切面(aspect)、通知(advice)、連接點(joinpoint),實現方式就是通過對目標對象的代理在連接點前後加入通知,完成統一的切面操作。
⑩ Spring框架的動態代理是干什麼用的
主要就是解耦和。還有提高開發效率。易於修改啊。
比如 一段記錄日誌的代碼。loger.log("some mothed invoke at "+new Date()); 沒有什麼難事。但是你所有方法。你都復制一下?那個太不靠譜了。
嗯。這個就是Java 模式 中的 代理模式。你可以看一下。看看那個。你就知道了spring 的代理。嗯。spring的代理,有兩種機制,一中是jdk的Proxy 還有一個是cglib 這個是基於集成實現的。嗯。就是super 使用重寫方法。然後在重寫方法中加入 super.thisMethod();
耦合度太高的話就會對你的程序未來升級帶來恨大的麻煩。嗯。說實話啊。嗯。你的項目要是一頂保證永不改變。那麼完全可以不管這個耦合度的問題。但是,jdk的升級。還有其他框架啊。技術的升級。都會對你 的系統帶來問題。和升級空間。所以,降低耦合度就是一直在做的。