java動態代理和cglib動態代理

來源:互聯網
上載者:User

動態代理應用廣泛,Spring,Struts等架構很多功能是通過動態代理,或者進一步封裝來實現的。

常見的動態代理模式實現有Java API提供的動態代理和第三方開源類庫CGLIB動態代理。

Java API提供的動態代理是基於類反射實現的,用到的類有:

java.lang.reflect.InvocationHandler;

java.lang.reflect.Method;

java.lang.reflect.Proxy;

其實現是通過Proxy類的newProxyInstance()方法產生代理對象。自訂動態代理類需要實現InvocationHandler介面,該介面只有一個invoke()方法。

CGLIB是通過產生java 位元組碼從而動態產生代理對象,因此需要位元組碼解析處理的依賴asm類庫,位元組碼動態產生的代理對象實際上是繼承了真實主題類的。這種實現方式需要匯入cglib和asm的類庫。下面用到的例子是cglib-2.2.2.jar, asm-3.3.1.jar。cglib使用了MethodInterceptor,其中的方法是intercept(),這是攔截的概念,很容易就想到了Struts2的攔截器。

比較之下,Java API提供的動態代理需要面向介面,產生代理對象,因此真實主題實作類別必須實現了介面才可以。而CGLIB不需要面向介面,可以代理簡單類,但由於動態代理對象是繼承真實主題實作類別的,因此要求真實主題實作類別不能是final的。

下面是實現的例子。

首先,為了看到動態代理可以根據不同類動態產生不同代理的效果,我們建立兩個介面,及其實作類別。

package leon.aj.dynproxy.target;public interface Hello {public String sayHello(String name);}

實作類別:

package leon.aj.dynproxy.target;public class HelloImpl implements Hello {@Overridepublic String sayHello(String name) {String s = "Hello, "+name;System.out.println(this.getClass().getName()+"->"+s);return s;}}

另一介面和實作類別:

package leon.aj.dynproxy.target;public interface UserDao {public boolean login(String username,String password);}

package leon.aj.dynproxy.target;public class UserDaoImpl implements UserDao {@Overridepublic boolean login(String username, String password) {String user = "("+username+","+password+")";System.out.println(this.getClass().getName()+"-> processing login:"+user);return true;}}

應用Java API實現的動態代理類:

package leon.aj.dynproxy.java;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class JavaDynProxy implements InvocationHandler{private Object target;public Object getProxyInstance(Object target){this.target = target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object result = null;System.out.println("before target method...");result = method.invoke(target, args);System.out.println("after target method...");return result;}}

測試:

package leon.aj.dynproxy.java;import leon.aj.dynproxy.target.Hello;import leon.aj.dynproxy.target.HelloImpl;import leon.aj.dynproxy.target.UserDao;import leon.aj.dynproxy.target.UserDaoImpl;public class TestJavaProxy {public static void main(String[] args) {JavaDynProxy proxy = new JavaDynProxy();Hello hello = (Hello)proxy.getProxyInstance(new HelloImpl());String s = hello.sayHello("Leon");System.out.println(s);UserDao userDao = (UserDao) proxy.getProxyInstance(new UserDaoImpl());userDao.login("Leon", "1234");System.out.println(userDao.getClass().getName());}}

下面是採用cglib實現的例子:

package leon.aj.dynproxy.cglib;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor {private Object target;      public Object getProxyInstance(Object target) {      this.target = target;        Enhancer enhancer = new Enhancer();          enhancer.setSuperclass(this.target.getClass());          enhancer.setCallback(this);  // call back method        return enhancer.create();  // create proxy instance    }  @Overridepublic Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("before target method...");Object result = proxy.invokeSuper(target, args);System.out.println("after target method...");return result;}}

測試類別:

package leon.aj.dynproxy.cglib;import leon.aj.dynproxy.target.Hello;import leon.aj.dynproxy.target.HelloImpl;import leon.aj.dynproxy.target.UserDaoImpl;public class TestCiglib {public static void main(String[] args) {CglibProxy proxy = new CglibProxy();Hello hello = (Hello) proxy.getProxyInstance(new HelloImpl());System.out.println(hello.sayHello("Leon"));UserDaoImpl userDao = (UserDaoImpl) proxy.getProxyInstance(new UserDaoImpl());userDao.login("Leon", "1234");System.out.println(userDao.getClass().getSuperclass());//看動態代理執行個體的父類}}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.