国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

java動(dòng)態(tài)代理淺析

2019-11-14 20:54:45
字體:
供稿:網(wǎng)友
java動(dòng)態(tài)代理淺析

最近在公司看到了mybatis與sPRing整合中MapperScannerConfigurer的使用,該類通過反向代理自動(dòng)生成基于接口的動(dòng)態(tài)代理類。

于是想起了java的動(dòng)態(tài)代理,然后就有了這篇文章。

本文使用動(dòng)態(tài)代理模擬處理事務(wù)的攔截器。

接口:

public interface UserService {    public void addUser();    public void removeUser();    public void searchUser();}

實(shí)現(xiàn)類:

public class UserServiceImpl implements UserService {    public void addUser() {        System.out.println("add user");    }    public void removeUser() {        System.out.println("remove user");    }    public void searchUser() {        System.out.println("search user");    }}
java動(dòng)態(tài)代理的實(shí)現(xiàn)有2種方式1.jdk自帶的動(dòng)態(tài)代理

使用jdk自帶的動(dòng)態(tài)代理需要了解InvocationHandler接口和Proxy類,他們都是在java.lang.reflect包下。

InvocationHandler介紹:

InvocationHandler是代理實(shí)例的調(diào)用處理程序?qū)崿F(xiàn)的接口。

每個(gè)代理實(shí)例都具有一個(gè)關(guān)聯(lián)的InvocationHandler。對代理實(shí)例調(diào)用方法時(shí),這個(gè)方法會調(diào)用InvocationHandler的invoke方法。

Proxy介紹:

Proxy 提供靜態(tài)方法用于創(chuàng)建動(dòng)態(tài)代理類和實(shí)例。

實(shí)例(模擬AOP處理事務(wù)):

public class TransactionInterceptor implements InvocationHandler {    private Object target;    public void setTarget(Object target) {        this.target = target;    }        @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("start Transaction");        method.invoke(target, args);        System.out.println("end Transaction");        return null;    }}

測試代碼:

public class TestDynamicProxy {    @Test    public void testJDK() {        TransactionInterceptor transactionInterceptor = new TransactionInterceptor();        UserService userService = new UserServiceImpl();        transactionInterceptor.setTarget(userService);        UserService userServiceProxy =                (UserService) Proxy.newProxyInstance(                        userService.getClass().getClassLoader(),                        userService.getClass().getInterfaces(),                        transactionInterceptor);        userServiceProxy.addUser();    }}

測試結(jié)果:

start Transactionadd userend Transaction

很明顯,我們通過userServiceProxy這個(gè)代理類進(jìn)行方法調(diào)用的時(shí)候,會在方法調(diào)用前后進(jìn)行事務(wù)的開啟和關(guān)閉。

2. 第三方庫cglib

CGLIB是一個(gè)功能強(qiáng)大的,高性能、高質(zhì)量的代碼生成庫,用于在運(yùn)行期擴(kuò)展Java類和實(shí)現(xiàn)Java接口。

它與JDK的動(dòng)態(tài)代理的之間最大的區(qū)別就是:

JDK動(dòng)態(tài)代理是針對接口的,而cglib是針對類來實(shí)現(xiàn)代理的,cglib的原理是對指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對final修飾的類進(jìn)行代理。

實(shí)例:

public class UserServiceCallBack implements MethodInterceptor {    @Override    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {        System.out.println("start Transaction by cglib");        methodProxy.invokeSuper(o, args);        System.out.println("end Transaction by cglib");        return null;    }}

測試代碼:

public class TestDynamicProxy {    @Test    public void testCGLIB() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(UserServiceImpl.class);        enhancer.setCallback(new UserServiceCallBack());        UserServiceImpl proxy = (UserServiceImpl)enhancer.create();        proxy.addUser();    }}

測試結(jié)果:

start Transaction by cglibadd userend Transaction by cglib
結(jié)束語

簡單講解了JDK和cglib這2個(gè)動(dòng)態(tài)代理,之后會再寫篇文章講講MapperScannerConfigurer的原理實(shí)現(xiàn)。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 那坡县| 保康县| 进贤县| 长泰县| 马关县| 高尔夫| 保靖县| 邛崃市| 新源县| 堆龙德庆县| 读书| 眉山市| 资兴市| 东港市| 陵水| 洪洞县| 温泉县| 嘉善县| 奉节县| 阜城县| 丹东市| 伽师县| 太原市| 林周县| 天等县| 云安县| 仁布县| 娱乐| 广西| 呼玛县| 太湖县| 安新县| 长葛市| 富民县| 乐至县| 宜宾县| 黎川县| 福鼎市| 江山市| 延吉市| 东乡县|