JDK动态代理和CGLIB

来源:互联网 发布:小满软件好不好 编辑:程序博客网 时间:2024/05/24 06:06

spring的两大功能,ioc和aop,其实aop的实现使用了jdk自带的动态代理和CGLIB代理模式,这两者主要区别是,jdk动态代理主要是面对被代理对象的接口,如果被代理对象没有实现其他接口,则这种办法无法使用,CGLIB则是面对被代理对象。下面用代码来解释两者的区别;
JDK Proxy

IHello interfacepackage com.baiguomin.proxy;public interface IHello {    void sayHello();}Hello implements IHellopackage com.baiguomin.proxy;public class Hello implements IHello {    public void sayHello() {        System.out.println("hello world!");    }}ProxyHandler:package com.baiguomin.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class ProxyHandler implements InvocationHandler {    private Object obj;    public ProxyHandler(Object obj){        this.obj = obj;    }    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        Object result;        System.out.println("============before===========");        result = method.invoke(obj, args);        System.out.println("============after===========");        return result;    }}Test:package com.baiguomin.proxy;import java.lang.reflect.Proxy;public class Test {    public static void main(String[] args) {        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");        Hello hello = new Hello();        IHello proxyHello = (IHello)Proxy.newProxyInstance(IHello.class.getClassLoader(),new Class[]{IHello.class},new ProxyHandler(hello));        proxyHello.sayHello();    }}

result :
============before===========
hello world!
============after===========

cglib要注意的是版本问题,否则会出现一些版本不兼容的问题,这边是用的是

<dependency>    <groupId>cglib</groupId>    <artifactId>cglib</artifactId>    <version>2.2.2</version></dependency><dependency>    <groupId>asm</groupId>    <artifactId>asm</artifactId>    <version>3.3.1</version></dependency>

cglib的用法:

Hello Class 没有实现任何接口package com.baiguomin.cglib;public class Hello {    public void sayHello(){        System.out.println("hello world~!");    }}CGLIBProxy 更像是一个通用类package com.baiguomin.cglib;import java.lang.reflect.Method;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor{    public Object intercept(Object object, Method method, Object[] args,            MethodProxy proxy) throws Throwable {        Object result;        System.out.println("---before--");        result = proxy.invokeSuper(object, args);        System.out.println("---atfer--");        return result;    }}Facotry class 用来生成增强后的被代理对象类package com.baiguomin.cglib;import net.sf.cglib.proxy.Enhancer;public class Factory {    public static Hello getInstance(CglibProxy proxy){        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(Hello.class);        enhancer.setCallback(proxy);        Hello hello = (Hello) enhancer.create();        return hello;    }}Test Classpackage com.baiguomin.cglib;public class Test {    public static void main(String[] args) {        CglibProxy proxy = new CglibProxy();        Hello hello = Factory.getInstance(proxy);        hello.sayHello();    }}

result:
—before–
hello world~!
—atfer–

这是两者的基本用法,源码分析的话稍候奉上。Spring中使用的AspectJ使用了动态代理的模式,在具体使用的时候,会自动选择jdk动态代理和cglib中的一个。
主要特点是: jdk动态代理生成代理类快,执行较慢,cglib生成代理类慢,执行较快。

0 0
原创粉丝点击