JDK动态代理和cglib生成代理

http://blog.csdn.net/zdp072/article/details/25657995
[ JDK生成代理 ]
JDK中给我们提供了一个Proxy类可以动态的给我们生成代理.
假定我们要做一个权限管理系统, 需要控制用户对某一个方法的访问. 如果user为null, 那么不让用户访问save方法.

① 接口类: PersonService
public interface PersonService {  
    public void save();  
}  

② 实现类: PersonServiceImpl
public class PersonServiceImpl implements PersonService {  
    private String user;  
      
    public PersonServiceImpl(){  
    }  
      
    public PersonServiceImpl(String user) {  
        this.user = user;  
    }  
  
    public void save() {  
        System.out.println("执行了save()方法");  
    }  
  
    public String getUser() {  
        return user;  
    }  
} 

③ 生成代理类工厂: JDKProxyFactory
public class JDKProxyFactory implements InvocationHandler {  
    private Object targetObject; //代理的目标对象  
  
    public Object createProxyIntance(Object targetObject) {  
        this.targetObject = targetObject;  
        /** 
         * 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器 
         * 第二个参数设置代理类实现的接口 
         * 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法 
         */  
        return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),   
                                      this.targetObject.getClass().getInterfaces(),   
                                      this);  
    }  
  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        PersonServiceImpl ps = (PersonServiceImpl) this.targetObject;  
        Object result = null;  
        if (ps.getUser() != null) { // 如果user为null, 则无法调用目标方法  
            result = method.invoke(targetObject, args); // 把方法调用委派给目标对象  
        }  
        return result;  
    }  
}
 
④ 测试一把:
public class PersonServiceImplTest {  
    @Test  
    public void testJDKProxy() {  
        JDKProxyFactory factory = new JDKProxyFactory();  
        PersonService personService = (PersonService) factory.createProxyIntance(new PersonServiceImpl("zhangsan"));  
        personService.save();  
    }  
}  


[ CGLIB生成代理 ]
Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类。
使用CGLIB生成代理需要引入cglib-nodep-2.1_3.jar
① CBLIG生成代理工厂: CGlibProxyFactory
public class CGlibProxyFactory implements MethodInterceptor {  
    private Object targetObject;  
  
    public Object createProxyIntance(Object targetObject) {  
        this.targetObject = targetObject;  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.targetObject.getClass()); // 设置代理类的父类  
        enhancer.setCallback(this); // 设置回调函数  
        return enhancer.create();  
    }  
  
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {  
        PersonServiceImpl bean = (PersonServiceImpl) this.targetObject;  
        Object result = null;  
        if (bean.getUser() != null) { // 如果user为null, 则无法调用目标方法  
            result = methodProxy.invoke(targetObject, args);  
        }  
        return result;  
    }  
} 

② 测试一把
public class PersonServiceImplTest {  
    @Test  
    public void testCGLIBProxy() {  
        CGlibProxyFactory factory = new CGlibProxyFactory();  
        PersonService personService = (PersonServiceImpl) factory.createProxyIntance(new PersonServiceImpl("lisi"));  
        personService.save();  
    }  
} 


[ 比较两种代理 ]
1. 使用JDK的动态代理, 被代理类一定要实现了某个接口, 而使用CGLIB, 被代理类没有实现任何接口也可以实现动态代理功能,
2. 因为采用的是继承, 所以cglib无法对使用final修饰的类使用代理.
3. CGLIB的速度要远远快于JDK Proxy动态代理.

你可能感兴趣的:(JDK动态代理)