您的位置:首页 > 编程语言 > Java开发

JDK动态代理和CGLIB

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

JDK Proxy

IHello interface
package com.baiguomin.proxy;

public interface IHello {

void sayHello();
}
Hello implements IHello
package 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 Class
package 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生成代理类慢,执行较快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jdk spring 对象 aop