zoukankan      html  css  js  c++  java
  • java 进阶一:代理和动态代理

    静态代理:

      定义顶级接口:Iservice

    //目标类和代理类都实现该接口
    public interface Iservice {
        public String server();
    }

      定义目标类:ServiceImp 实现 Iservice接口

    // 目标类
    public class ServiceImp implements Iservice {
        @Override
        public String server() {
            return "hello";
        }
    }

      定义代理类:ServiceProxy 实现 Iservice 接口,将目标类中目标方法的返回值变为大写字符

    // 代理类
    public class ServiceProxy implements Iservice {
        
        Iservice target;
        
        public ServiceProxy() {
        }
        
        public ServiceProxy(Iservice target) {
            this.target = target;
        }
    
        @Override
        public String server() {
            return target.server().toUpperCase();
        }
    }

    测试:

    public class Test {
        public static void main(String[] args) {
            Iservice target=new ServiceImp();
            Iservice proxy=new ServiceProxy(target);
            System.out.println(proxy.server());
        }
    }

    动态代理的两种实现方式

      1、使用JDK的Proxy实现代理,要求目标类和代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。

      2、对于无接口的类,需要使用CGLIB来实现代理。CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类就是代理对象。因此,使用CGLIB生成动态代理,要求目标类必须能被继承,即不能是final修饰的类。

      CGLIB(Code Generation Library)是一个开源项目,是一个强大的、高性能的、高质量的代码生成类库。它可以在运行期间扩展和增强java类。Hibernate用它来实现持久对象的字节码的动态生成,Spring用它来实现AOP编程。CGLIB包的底层是通过使用字节码处理框架ASW(Java字节码处理框架),来转换字节码并生成新的类。CGLIB是通过对字节码进行增强来生成代理的。

    相关实例代码:

      1、Proxy实现:

    public class Test {
        public static void main(String[] args) {
            // 定义目标对象
            Iservice target=new ServiceImp();
            // 定义目标对象的代理对象
            Iservice myproxy=(Iservice) Proxy.newProxyInstance(
                    target.getClass().getClassLoader(), // 目标类的类加载器
                    target.getClass().getInterfaces(), //目标类实现的接口
                    new InvocationHandler() {
                // proxy:代理对象
                // method:目标方法
                // args:目标方法的参数
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) 
                        throws Throwable {
                    Object result=method.invoke(target, args);
                    if ("server".equals(method.getName())) {
                        result = result.toString().toUpperCase();
                    }
                    return result;
                }
                
            });
            System.out.println(myproxy.server());
        }
    }

      2、CGLIB实现:

      定义目标类:Service

    public class Service {
        public String server(){
            return "hello";
        }
    }

      创建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 {
        private Service target;
        public CglibProxy() {
        }
        public CglibProxy(Service target){
            this.target=target;
        }
        // 创建cglib代理对象
        public Service myProxy(){
            Service service=new Service();
            Enhancer enhancer=new Enhancer();
            // 指定父类,即要增强的目标类
            enhancer.setSuperclass(Service.class);
            // 指定回调接口对象
            enhancer.setCallback(this);
            // 创建cglib代理对象
            return (Service) enhancer.create();
        }
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            Object result=method.invoke(target, args);
            if ("server".equals(method.getName())) {
                result = result.toString().toUpperCase();
            }
            return result;
        }
    }

       测试:

    public class Test {
        public static void main(String[] args) {
            // 创建目标对象
            Service target=new Service();
            // 创建目标对象的代理对象
            Service proxy=new CglibProxy(target).myProxy();
            System.out.println(proxy.server());
        }
    }
  • 相关阅读:
    day 16
    day 15
    day 14
    day 13
    Unity Shader UnityCG.cginc
    Unity Shader 包含内置文件
    Unity Shader 如何使用属性
    Unity Shader 顶点/片元着色器的基本结构
    Unity Shader 的基础结构
    git文件名大小敏感
  • 原文地址:https://www.cnblogs.com/hypnus-ly/p/8429123.html
Copyright © 2011-2022 走看看