zoukankan      html  css  js  c++  java
  • JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)

    AOP用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 = value;
      }
    }
  • 相关阅读:
    夜神 虚拟机调试 HBuilder 移动端应用
    maven filter 文件分环境打包部署小问题
    fatal: remote error: CAPTCHA required
    程序员今年是这样计划的
    线程池shutdown与shutdownnow 小例子
    JAVA知识点脉络记忆-刻意练习
    日志
    (职员)2015-12-02 星期三 日志
    (职员)2015-12-04 星期五 周志
    (职员)2015-12-04 星期五 日志
  • 原文地址:https://www.cnblogs.com/starcrm/p/5885181.html
Copyright © 2011-2022 走看看