CGLib动态代理


         我们知道JDK动态代理只能够代理实现了接口的类,而对于没有实现接口的类,jdk就显得无能为力.这种情况下,我们就选择使用cglib来为指定的目标类进行代理,它为目标类生成一个子类,然后覆盖其中的方法实现增强.

 

cglib如何实现代理,我们来看一段源码.


没有实现接口的类:


public class GreetingImpl {
	
    public void sayHello(String name) {          
        System.out.println("Hello! " + name);  
    } 
} 


cglib代理类:


import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * CGLib动态代理类
 * @author ghy
 * version 3.0.0 , 2015年5月23日 下午3:37:40
 */
public class CGLibDynamicProxy implements MethodInterceptor {  
 
	//用单例模式创建代理对象
    private static CGLibDynamicProxy instance = new CGLibDynamicProxy();  
 
    
    private CGLibDynamicProxy() {  
    }  
 
    public static CGLibDynamicProxy getInstance() {  
        return instance;  
    }  
 
    //得到代理的方法
    @SuppressWarnings("unchecked")  
    public <T> T getProxy(Class<T> cls) {  
        return (T) Enhancer.create(cls, this);  
    }  
 
    //拦截被代理类的方法,在前后分别执行before()和after()方法
    @Override 
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {  
        before();  
        Object result = proxy.invokeSuper(target, args);  
        after();  
        return result;  
    }  
 
    //拦截的方法执行前插入的方法
    private void before() {  
        System.out.println("Before");  
    }  
    //拦截的方法执行后插入的方法
    private void after() {  
        System.out.println("After");  
    }  
}


Client客户端:


public class Client {
	public static void main(String[] args) {  
		GreetingImpl greetingImpl = CGLibDynamicProxy.getInstance().getProxy(GreetingImpl.class);  
		greetingImpl.sayHello("Jack");  
    } 
}


运行结果:

                    CGLib动态代理_第1张图片

        现在,有了jdkcglib代理,动态地生成代理对象并执行我们想要插入的方法已经不是难事.可是,我们看到以上所有要插入的代码都写死在了代理类中,这是不科学的.我们的目标是,各种业务是独立的,各种服务诸如日志/权限/工作流等也都是独立的,通过代理将二者动态地联合起来,达到我们想要的结果.所以,AOP的实现还需要改进.因为到目前为止,我们所做的还不是最灵活的AOP.


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