CGLib动态代理

来源:互联网 发布:知乎 中国外交手段 编辑:程序博客网 时间:2024/05/22 13:20


         我们知道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");      } }


运行结果:

                    

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


1 0