• 代理模式


    1. 静态代理:

    1-1. interface

    public interface Hello {
    
        public void talk();
    }

    1-2. some impl class

    public class HelloImpl implements Hello {
    
        @Override
        public void talk() {
            System.out.println("hi, helloImpl.");
        }
    
    }

    1-3. some proxy class

    public class HelloProxy implements Hello {
    
        private Hello hello;
        public HelloProxy(){
            hello = new HelloImpl();
        }
        @Override
        public void talk() {
            before();
            hello.talk();
            after();
        }
    
        private void after() {
            System.out.println("do something after talk...");        
        }
        private void before() {
            System.out.println("do something before talk...");
        }
        public static void main(String[] args) {
            HelloProxy hProxy = new HelloProxy();
            hProxy.talk();
        }
    
    }

    2. JDK动态代理

    2-1 dynamic proxy class(1.0 version)

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class DynamicProxy implements InvocationHandler {
    
        private Object target;
        public DynamicProxy (Object target){
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            before();
            Object result = method.invoke(target, args);
            after();
            return result;
            
        }
        private void after() {
            System.out.println("after ...");
        }
        private void before() {
            System.out.println("before....");
        }
    
    }

    2-2. 测试

    import java.lang.reflect.Proxy;
    
    public class TestProxy {
    
        public static void main(String[] args) {
            Hello hello = new HelloImpl();
            DynamicProxy dProxy = new DynamicProxy(hello);
            Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),
                                  hello.getClass().getInterfaces(), 
                                  dProxy);
            helloProxy.talk();
        }
    }

    2-3. dynamic proxy class(2.0 version)

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class DynamicProxy implements InvocationHandler {
    
        private Object target;
        public DynamicProxy (Object target){
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            before();
            Object result = method.invoke(target, args);
            after();
            return result;
            
        }
        public <T> T getProxy(){
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(), 
                    this);
        }
        private void after() {
            System.out.println("after ...");
        }
        private void before() {
            System.out.println("before....");
        }
    
    }

    2-4 Test

    import java.lang.reflect.Proxy;

    public class TestProxy {

        public static void main(String[] args) {
            DynamicProxy dProxy = new DynamicProxy(new HelloImpl());
            Hello helloProxy = dProxy.getProxy();
            helloProxy.talk();
        }
    }

    3 CGLIB动态代理

    jdk动态代理是基于接口的, 如果一个类没有实现任何接口,这时就不管用了

    3-1. CGLib代理类

    cglib 提供的是方法级别的代理,也可以理解为对方法的拦截

    import java.lang.reflect.Method;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class CGLibProxy implements MethodInterceptor {
    
        @SuppressWarnings("unchecked")
        public <T> T getProxy(Class<T> cls){
            return (T) Enhancer.create(cls, this);
        }
        @Override
        public Object intercept(Object obj, Method method, Object[] args,
                MethodProxy proxy) throws Throwable {
            before();
            Object result = proxy.invokeSuper(obj, args);
            after();
            return result;
        }
    
        private void after() {
            // TODO Auto-generated method stub
        }
    
        private void before() {
            // TODO Auto-generated method stub
        }
    
    }

    3-2. Test

    这里不需要任何的接口信息

    public class TestCLIib {
    
        public static void main(String[] args) {
            CGLibProxy cgLibProxy = new CGLibProxy();
            HelloImpl helloProxy = cgLibProxy.getProxy(HelloImpl.class);
            helloProxy.talk();
        }
    }

    需要引入asm的相关jar, 引用asm-5.1.2.jar时报错, 引用com.springsource.org.objectweb.asm-3.2.0.jar可以

  • 相关阅读:
    序列、元组、列表(基本的增、删、改、查)
    Python基础运算符(算数、比较、赋值、逻辑、成员)
    2015年9月14日记事
    2014年3月31日梦
    华为S5700系列交换机配置文件导出、导入
    C语言单链表简单实现(简单程序复杂化)
    北邮《大学英语2》第三次阶段作业带答案
    C++走向远洋——30(六周,项目一1.0)
    C++走向远洋——29(长方柱类)
    C++走向远洋——28(项目三,时间类,2)
  • 原文地址:https://www.cnblogs.com/rocky-fang/p/5454773.html
Copyright © 2020-2023  润新知