首页 > 代码库 > JAVA动态代理和方法拦截(使用CGLib实现AOP)

JAVA动态代理和方法拦截(使用CGLib实现AOP)

经典的AOP一般通过Spring框架,实际上用CGLib更简便、更可控。

动态代理的实现非常优雅。

 

实体类:

public class SampleClass {    public String MyFunction1(String input) {        System.out.println("MyFunction1方法被调用:Hello:" + input);        return "Hello:" + input;    }    public String MyFunction2(String input) {        System.out.println("MyFunction2方法被调用:Hello:" + input);        return "Hello:" + input;    }}

 

 

import net.sf.cglib.proxy.Callback;import net.sf.cglib.proxy.Dispatcher;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.FixedValue;import net.sf.cglib.proxy.LazyLoader;import net.sf.cglib.proxy.NoOp;import net.sf.cglib.proxy.ProxyRefDispatcher;public class CgLibTest {        private static String MyName = "";    public static void main(String[] args) {        MyName = "王昕";                DoAOP();        Enhancer enhancer1 = EnhancerNoOp();                SampleClass proxy = (SampleClass) enhancer1.create();        String strOutput = proxy.MyFunction2("赵七");        System.out.println("EnhancerNoOp:"+strOutput);                Enhancer enhancer2 = EnhancerFixedValue();                SampleClass proxy2 = (SampleClass) enhancer2.create();        String strOutput2 = proxy2.MyFunction2("赵七");        System.out.println("EnhancerFixedValue:"+strOutput2);            }    private static void DoAOP() {        MyInterceptor cglib = new MyInterceptor();        SampleClass bookCglib = (SampleClass) cglib                .getInstance(new SampleClass());        bookCglib.MyFunction2("张三");    }    // 该回调将替代原类的方法实现    private static Enhancer EnhancerFixedValue() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(SampleClass.class);                enhancer.setCallback(new FixedValue() {            @Override            public Object loadObject() throws Exception {                //返回 MyName 作为输入参数的;                return new SampleClass().MyFunction2(MyName);            }        });        return enhancer;    }        //执行原(Super)类方法    private static Enhancer EnhancerNoOp() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(SampleClass.class);                enhancer.setCallback(NoOp.INSTANCE);        return enhancer;    }        //延迟加载    private static Enhancer EnhancerLazyLoader() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(SampleClass.class);                enhancer.setCallback(new LazyLoader() {            @Override            public Object loadObject() throws Exception {                //return "回调后的返回值";                return new SampleClass().MyFunction2(MyName);            }        });        return enhancer;    }        private static Enhancer EnhancerProxyRefDispatcher(final String obj1) {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(SampleClass.class);                enhancer.setCallback(new ProxyRefDispatcher() {            @Override            public Object loadObject(Object obj2) throws Exception {                return new SampleClass().MyFunction2(obj1 + (String)obj2);            }        });        return enhancer;    }}

 

AOP拦截模拟类:

import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class MyInterceptor implements MethodInterceptor {      private Object target;        public Object getInstance(Object target) {          this.target = target;          Enhancer enhancer = new Enhancer();          enhancer.setSuperclass(this.target.getClass());          // 回调方法          enhancer.setCallback(this);          // 创建代理对象          return enhancer.create();      }        @Override      // 回调方法      public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,              MethodProxy proxy) throws Throwable {          System.out.println("拦截前,做些事情");          proxy.invokeSuper(obj, args);          System.out.println("拦截后,再做些事情");          return null;         }    }  

 

输出:

拦截前,做些事情
MyFunction2方法被调用:Hello:张三
拦截后,再做些事情
MyFunction2方法被调用:Hello:赵七
EnhancerNoOp:Hello:赵七
MyFunction2方法被调用:Hello:王昕
EnhancerFixedValue:Hello:王昕   

 

 

MethodDelegate

方法委托:  实现类似C#的委托。将方法调用绑定到某个接口的特定方法

    public void testMethodDelegate() throws Exception {        SampleBean bean = new SampleBean();        bean.setValue("Hello cglib!");        BeanDelegate delegate = (BeanDelegate) MethodDelegate.create(bean,                "getValue", BeanDelegate.class);        assertEquals("Hello world!", delegate.getValueFromDelegate2());    }    public interface BeanDelegate {        //String getValueFromDelegate1();        String getValueFromDelegate2();    }

 

BulkBean 

使用数组访问bean的访问器方法调用

    public void testBulkBean() throws Exception {        BulkBean bulkBean = BulkBean.create(SampleBean.class,                new String[] { "getValue" }, new String[] { "setValue" },                new Class[] { String.class });        SampleBean bean = new SampleBean();        bean.setValue("Hello world!");        assertEquals(1, bulkBean.getPropertyValues(bean).length);        assertEquals("Hello world!", bulkBean.getPropertyValues(bean)[0]);        bulkBean.setPropertyValues(bean, new Object[] { "Hello cglib!" });        assertEquals("Hello cglib!", bean.getValue());    }
public class SampleBean {  private String value;  public String getValue() {    return value;  }  public void setValue(String value) {    this.value =http://www.mamicode.com/ value;  }}

 

JAVA动态代理和方法拦截(使用CGLib实现AOP)