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

首頁(yè) > 編程 > Java > 正文

java實(shí)現(xiàn)動(dòng)態(tài)代理方法淺析

2019-11-26 15:27:13
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

一些Java項(xiàng)目中在mybatis與spring整合中有MapperScannerConfigurer的使用,該類通過(guò)反向代理自動(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。對(duì)代理實(shí)例調(diào)用方法時(shí),這個(gè)方法會(huì)調(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;  }}

測(cè)試代碼:

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

測(cè)試結(jié)果:

start Transactionadd userend Transaction

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

2. 第三方庫(kù)cglib

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

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

JDK動(dòng)態(tài)代理是針對(duì)接口的,而cglib是針對(duì)類來(lái)實(shí)現(xiàn)代理的,cglib的原理是對(duì)指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對(duì)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;  }}

測(cè)試代碼:

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

測(cè)試結(jié)果:

start Transaction by cglibadd userend Transaction by cglib

感興趣的讀者可以實(shí)際測(cè)試一下本文實(shí)例,相信會(huì)有很大的收獲。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 商都县| 观塘区| 当雄县| 鄂托克前旗| 荃湾区| 微山县| 怀安县| 沂南县| 武陟县| 新和县| 屏东县| 涿鹿县| 环江| 庄河市| 且末县| 台南市| 曲松县| 高雄县| 阳信县| 新巴尔虎左旗| 新巴尔虎右旗| 高要市| 历史| 邮箱| 商城县| 改则县| 如东县| 梁河县| 虎林市| 澄迈县| 丘北县| 子长县| 恩施市| 周宁县| 吴江市| 亚东县| 华亭县| 庄河市| 清水河县| 石家庄市| 竹山县|