静态代理:由程序员创建或者特定工具生成,再对其编译。代理类在程序运行前就已经存在。
缺点:不够灵活,原接口中添加一个方法,代理类就需要进行相应地修改。
动态代理:程序运行时,通过反射机制动态创建。
优点:接口中所有的方法都被移动到一个集中的方法中处理(invoke),当接口中方法比较多时,我们可以灵活处理,不需要像静态代理那样一个一个中转。
动态代理必须实现invocationHandler接口,实现invoke方法。invoke方法就是调用被代理接口的所有方法时需要被调用的。bind方法返回的是被代理接口的一个代理对象。
public class DynamicProxy implements InvocationHandler{
Object target;
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object result = null;
System.out.println("DynamicProxy start!");
result = method.invoke(target, args);
System.out.println("DynamicProxy end!");
return result;
}
}
public class TestDynamicProxy {
public static void main(String[] args){
DynamicProxy dynamicProxy = new DynamicProxy();
HelloWorld helloWorld = (HelloWorld) dynamicProxy.bind(new HelloWorldImp());
helloWorld.print();
helloWorld.say();
}
}
用InvocationHandler 与 Proxy实现的动态代理有一个缺点,代理对象必须实现接口。如果没有实现接口就不能用JDK代理,这是可以使用CGLIB动态代理。实现原理是对指定目标类生成一个子类,并覆盖其中的方法增强实现。但因为采用了继承,所以不能对final修饰的类进行代理。
CGLibHelloWorldImple没有实现接口,要产生该类的动态代理不能使用JDK自带的类,可以使用CGLib
public class CGLibHelloWorldImpl {
public void print() {
// TODO Auto-generated method stub
System.out.println("Hello World!");
}
public void say() {
// TODO Auto-generated method stub
System.out.println("say method!");
}
public void talk() {
// TODO Auto-generated method stub
System.out.println("talk!");
}
}
//CGLibHelloWorldProxy中的getInstance方法会产生一个代理目标target的代理对象。
public class CGLibHelloWorldProxy implements MethodInterceptor{
private Object target;
/**
* 创建代理对象
*
* @param target
* @return proxy object of target
*/
public Object getInstance(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());//设置父类,返回的代理对象是target的子类,覆盖了target的方法并增强
enhancer.setCallback(this);//回调方法
return enhancer.create();//创建代理对象
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object result = null;
System.out.println("CGLIB DynamicProxy start!");
result = methodProxy.invoke(this.target, args);
System.out.println("CGLIB DynamicProxy end!");
return result;
}
}
//代理的测试代码
public class CGLibProxyTest {
public static void main(String[] args){
CGLibHelloWorldProxy proxy = new CGLibHelloWorldProxy();
CGLibHelloWorldImpl helloWorld = (CGLibHelloWorldImpl) proxy.getInstance(new CGLibHelloWorldImpl());
System.out.println(helloWorld.getClass());
helloWorld.say();
}
}
两种代理生成方式的比较:
1.使用JDK的动态代理, 被代理类一定要实现了某个接口, 而使用CGLIB, 被代理类没有实现任何接口也可以实现动态代理功能,
2. 因为采用的是继承, 所以cglib无法对使用final修饰的类使用代理.
3. CGLIB的速度要远远快于JDK Proxy动态代理.
分享到:
相关推荐
1:静态代理出现的实际背景,静态代理时如何演化成动态代理 2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic进行通信) 3: 动态代理使用到基础理论:ClassLoader 加载.class字节码...
结合spring框架实现的动态代理代理,spring,Proxy
JDK动态代理,关于jdk动态代理的问题!详细的说明!JDK动态代理JDK动态代理
动态代理及其生成的代理类,可以反编译查看其类的结构。
动态代理设计模式 日志和源码 动态代理设计模式 日志和源码
通过动态代理,在单元格中添加spinbox,checkbox,combobox。
对jdk中的动态代理执行过程进行了详细跟踪,并反编译了动态代理调用自动生成的代理类,并对其进行了详细讲解。
jdk 的动态代理和CGLIB代理
spring之AOP(动态代理),包括jdk动态代理和CGLib动态代理
java静态代理 jdk动态代理 cglib动态代理 代理原理
动态代理是使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象。 而不用你创建类文件。不用写java文件。 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。jdk动态代理,必须有接口,目标类必须...
主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。主要包括:1. AOP的常见概念 2. 静态代理 3. jdk动态代理 4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB ...
动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理
Java实现动态代理的两种方式。 相对来说cglib更加方便。可以实现为实现接口的类(非final类)
java动态代理 public class HireProxy implements InvocationHandler { //被代理的真实角色 private Object obj; public HireProxy(Object obj) { super(); this.obj = obj; } //第二个参数method,被...
动态代理和静态代理demo
java动态代理 完整版 java动态代理 完整版 java动态代理 完整版 java动态代理 完整版 java动态代理 完整版
java代理机制 JDK动态代理和cglib代理 详解
java动态代理例子,这里面有两个例子,一个是jdk的动态代理,一个是cglib的动态代理,让你明白什么是动态代理,动态代理可以做什么。
JAVA静态代理和动态代理