日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java使用Proxy和CGLib实现动态代理

發布時間:2024/10/8 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java使用Proxy和CGLib实现动态代理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ?在java中對一個方法進行改造有幾種方法可以實現,分別是最常用的繼承(extends)、動態代理和裝飾者模式。繼承是最簡單也是用的最多的方法,但是還是有一些場景不適用,這個時候就可能會用到動態代理。使用動態代理可以通過兩種方式實現:1、使用JDK自帶的Proxy實現代理。2、使用第三方類庫CGLib實現動態代理。

一、使用Proxy實現動態代理必須是需要代理的類實現了某一個接口,這樣才能實現代理

下面介紹兩種使用動態代理的方式實現的案例。

首先準備一個接口和兩個實現類對這兩個實現類分別進行改造

?

package com.zjp.dao;/*** 定義一個接口* @author zhujunpeng**/ public interface UserDao {public void addUser(); } package com.zjp.dao.impl;import com.zjp.dao.UserDao;public class UserDaoImpl implements UserDao{@Overridepublic void addUser() {System.out.println("添加用戶邏輯。。。。");}}

定義一個切點

package com.zjp.aspect;/*** 自定義切點* @author zhujunpeng**/ public class MyAspect {public void start(){System.out.println("start----");}public void end(){System.out.println("end----");} }

?

?

?

?

?

?

?

1、使用動態代理實現對一個方法進行改造

?

package com.zjp.proxy;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;import com.zjp.aspect.MyAspect; import com.zjp.dao.UserDao;/*** 動態代理的實現* @author zhujunpeng**/ public class MyProxy implements InvocationHandler{// 需要代理的對象private UserDao userDao;/*** 創建代理方法* @param userDao* @return*/public Object createProxy(UserDao userDao){this.userDao = userDao;// 1、類型加載器ClassLoader classLoader = MyProxy.class.getClassLoader();// 2、被代理對象實現的接口Class<?>[] clazz = userDao.getClass().getInterfaces();// 3、使用代理類、進行增強,返回的是代理后的對象return Proxy.newProxyInstance(classLoader, clazz, this);}/*** 每個代理對象都會走這個方法*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 聲明切面MyAspect myAspect = new MyAspect();myAspect.start();Object object = method.invoke(userDao, args);myAspect.end();return object;}}

增加測試方法

package com.zjp;import com.zjp.dao.UserDao; import com.zjp.dao.impl.UserDaoImpl; import com.zjp.proxy.MyProxy;/*** 測試方法* @author zhujunpeng**/ public class JdkProxyTest {public static void main(String[] args) {// 創建代理對象MyProxy myProxy = new MyProxy();UserDao userDao = new UserDaoImpl();userDao.addUser();UserDao userDaoProxy = (UserDao) myProxy.createProxy(userDao);userDaoProxy.addUser();} }


最后得到的結果為:?

添加用戶邏輯。。。。 start---- 添加用戶邏輯。。。。 end----

?

二、使用CGlib實現動態代理

如果要對某一個類實現動態代理,但是該類并沒有實現某個接口,那使用CGlib就非常合適。主要代碼如下:

一個沒有實現接口的類:

public class PersonServerImpl {public void save() {System.out.println("我是save方法");}public String getPersonName() {System.out.println("我是getPersonName方法");return "XX";}public void update() {System.out.println("我是update方法");}}

使用CGLib進行代理

?

package com.zjp.proxy;import java.lang.reflect.Method;import com.zjp.aspect.MyAspect; import com.zjp.dao.impl.PersonServerImpl;import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;/*** 使用cglib實現動態代理* * @author zhujunpeng**/ public class CglibProxyFactory implements MethodInterceptor {// 需要代理的對象private Object delegate;// 綁定對象,綁定的對象不是接口public Object createProxyInstance(Object delegate) {this.delegate = delegate;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(this.delegate.getClass());enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {MyAspect aspect = new MyAspect();aspect.start();Object invoke = method.invoke(delegate, args);aspect.end();return invoke;}}

代理類搞定之后,進行測試:

?

?

@Testpublic void proxyTest2() {CglibProxyFactory factory = new CglibProxyFactory();PersonServerImpl personServer = new PersonServerImpl();PersonServerImpl personServerProxy = (PersonServerImpl) factory.createProxyInstance(personServer);personServerProxy.save();}


通過測試之后也能實現與Proxy同樣的功能。

?

總結

以上是生活随笔為你收集整理的Java使用Proxy和CGLib实现动态代理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。