真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java動(dòng)態(tài)代理的理解與Cglib動(dòng)態(tài)代理實(shí)現(xiàn)-創(chuàng)新互聯(lián)

什么是動(dòng)態(tài)代理?

在嘉峪關(guān)等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需求定制開(kāi)發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),成都營(yíng)銷網(wǎng)站建設(shè),外貿(mào)營(yíng)銷網(wǎng)站建設(shè),嘉峪關(guān)網(wǎng)站建設(shè)費(fèi)用合理。

先說(shuō)下靜態(tài)代理:

也即是說(shuō),在程序運(yùn)行前,已經(jīng)有了編譯好的類,這個(gè)就是靜態(tài)代理,

動(dòng)態(tài)代理:

也即,在程序運(yùn)行前, 代理類并不存在,而是在程序運(yùn)行時(shí),動(dòng)態(tài)生成的類是動(dòng)態(tài)代理類。

可能會(huì)有如下思考

代理模式是怎樣的?用什么技術(shù)實(shí)現(xiàn)?

為什么要使用代理模式呢?有什么好處?

動(dòng)態(tài)代理的應(yīng)用場(chǎng)景有哪些?

先說(shuō)說(shuō)動(dòng)態(tài)代理的實(shí)現(xiàn)吧:

動(dòng)態(tài)代理主要使用的是Java 反射技術(shù):

JavaAPI 中關(guān)于InvocationHandler有大致這么一段描述,每個(gè)代理類都要實(shí)現(xiàn)InvocationHandler這個(gè)接口,每個(gè)代理類都會(huì)關(guān)聯(lián)到一個(gè)handle,

當(dāng)一個(gè)代理類調(diào)用方法時(shí),會(huì)轉(zhuǎn)到InvocationHandler的Invoke方法進(jìn)行調(diào)用。

以下代碼有引用以為牛人代碼

看下InvocationHandler源碼,我這就不再寫(xiě)一遍了。

public interface InvocationHandler

{

public abstract Object invoke(Object obj, Method method, Object aobj[])

throws Throwable;

}

這個(gè)invoke方法中有幾個(gè)參數(shù) :

obj:表示我們要調(diào)用的真實(shí)對(duì)象

method:表示我們要調(diào)用的真實(shí)對(duì)象的某個(gè)方法。

aobj[] :表示真實(shí)對(duì)象某個(gè)方法接受的參數(shù)。

怎么用這個(gè)InvocationHandler 這個(gè)接口,主要看proxy這個(gè)類:

Proxy是創(chuàng)建一個(gè)代理對(duì)象的類

Proxy這個(gè)類有這個(gè)一個(gè)方法:是用的最多的方法

public static Object newProxyInstance(ClassLoader classloader, Class aclass[], InvocationHandler invocationhandler)

throws IllegalArgumentException

參數(shù):

classloader: 定義了由那個(gè)ClassLoader對(duì)對(duì)象進(jìn)行加載

aclass[]: 是為代理對(duì)象提供了哪些接口,表示代理對(duì)象實(shí)現(xiàn)了這些接口,

invocationhandler: 表示代理對(duì)象調(diào)用方法時(shí)會(huì)關(guān)聯(lián)到那個(gè)invocationhandler

主要通過(guò)類Proxy與接口invocationhandler實(shí)現(xiàn)動(dòng)態(tài)代理:

看下具體動(dòng)態(tài)代理實(shí)現(xiàn)加深理解:

1.首先肯定是需要一個(gè)接口的:

public interface UserService {

public String getName(int id);

public Integer getAge(int id);

}

還需要這個(gè)接口的實(shí)現(xiàn),也就是代理對(duì)象:

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;

}

}

還需要自定義一個(gè)invocationhandler ,自己實(shí)現(xiàn)invoke方法:

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;

}

}

}

最后再看下proxy是怎樣的使用這個(gè)接口,還有invocationhandler的

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

public class TestProxy {

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));

}

}

以上可以看到可以清晰理解proxy的newproxyInstance是用來(lái)生成代理對(duì)象的, userService是指向具體 的實(shí)現(xiàn)

UserServiceImpl

給newproxyInstance方法傳入實(shí)際的classLoader,實(shí)際類對(duì)應(yīng)的接口,與調(diào)用類方法的invocationhandler即可實(shí)現(xiàn):

System.out.println("++++++before " + method.getName() + "++++++");

其實(shí)上面這個(gè)一行代碼就有***性質(zhì),aop時(shí)再詳細(xì)討論.

上面可以看到 使用這個(gè)反射技術(shù)實(shí)現(xiàn)動(dòng)態(tài)代理,需要定義一個(gè)接口,但是有時(shí)候其實(shí)不想定義接口,只希望定義好實(shí)現(xiàn)類,然后你再在方法運(yùn)行前,運(yùn)行后加些內(nèi)容即可。

這個(gè)就考慮了一個(gè)CGLIB這個(gè)可是不錯(cuò)的使用CGLIB實(shí)現(xiàn)動(dòng)態(tài)代理很方便。

Cglib 采用的是ASM字節(jié)碼技術(shù),利用字節(jié)碼生成代理類。效率比反射要高,但是不能代理final修身的類,clglib元素是集成被代理的類。final類不能被繼承。

下面看下cglib具體實(shí)現(xiàn):

下載 cglib包和asm包,你的工程需要依賴這兩個(gè)包:

首先需要一個(gè)非final類,不再和反射一樣需要一個(gè)接口了

public class StudentService {

public String getName(){

System.out.println("------getName------");

return "Tom";

}

public Integer getID(){

System.out.println("------getID------");

return 10;

}

}

接下來(lái)就看怎么代理上面的類了,需要定義一個(gè)攔截器:

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;

}

}

上面的interceptf方法和invocationhandler中的invoke方法類似,通過(guò)interceptf來(lái)真正調(diào)用方法invokeSuper:

最后看下Cglb具體怎么代理StudentService這個(gè)類吧:

import net.sf.cglib.proxy.Enhancer;

public class TestCglib {

public static void main(String[] args) {

CglibProxy cglibProxy = new CglibProxy();

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(StudentService.class);

enhancer.setCallback(cglibProxy);

StudentService o = (StudentService)enhancer.create();

System.out.println(o.getName());

// System.out.println(o.getID());

}

}

上面的o即是 代理類,該類可以訪問(wèn)真實(shí)的Studentservice方法:

運(yùn)行結(jié)果:無(wú)錫婦科檢查多少錢 http://www.120csfkyy.com/

++++++before CGLIB$getName$1++++++

getName

------getName------

++++++before CGLIB$getName$1++++++

Tom

使用Cglib 有啥好處?

看下面代碼:

public class TestCglib {

public static void main(String[] args) {

CglibProxy cglibProxy = new CglibProxy();

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(StudentService.class);

enhancer.setCallback(cglibProxy);

StudentService o = (StudentService)enhancer.create();

System.out.println(o.getName());

// System.out.println(o.getID());

Enhancer enhancer1 = new Enhancer();

enhancer1.setSuperclass(UserServiceImpl.class);

enhancer1.setCallback(cglibProxy);

UserServiceImpl obj = (UserServiceImpl)enhancer1.create();

System.out.println(obj.getName(1));

// System.out.println(o.getID());

}

}

只要寫(xiě)一個(gè)

cglibProxy

就可以是實(shí)現(xiàn)

對(duì)UserServiceImpl 與 StudentService進(jìn)行代理

減少了代碼的繁瑣,只有有這么一個(gè)代理就夠了,其次方便維護(hù),解耦合,要是有問(wèn)題,只要去找 原始類就可以了

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


網(wǎng)頁(yè)題目:Java動(dòng)態(tài)代理的理解與Cglib動(dòng)態(tài)代理實(shí)現(xiàn)-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://weahome.cn/article/dhcegs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部