Java使用Proxy和CGLib实现动态代理
生活随笔
收集整理的這篇文章主要介紹了
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();} }
最后得到的結果為:?
?
二、使用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实现动态代理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别克君威21款后视镜换一个整套壳需要多少
- 下一篇: 俏酒窝的高端酒和平价酒分布是怎样的?