美文网首页
java 动态代理 jdk和cglib

java 动态代理 jdk和cglib

作者: IT入门指南 | 来源:发表于2019-04-11 16:54 被阅读0次

    java中实现动态代理可以使用jdk提供的proxy实现,也可以通过cglib实现。二者主要的区别在于 proxy只能实代理实现了接口的类。cglib可以动态代理所有的 非final的类的非final方法

    利用 jdk 反射机制实现动态代理

    核心要点

    • 代理类必须实现 InvocationHandler 接口
    • 被代理的类必须继承一个接口

    测试代码

    • 接口类
    public interface jdkService {
        void hello();
    }
    
    • 接口实现类
    public class Service implements jdkService {
        public Service(String name) {
            this.name = name;
        }
        public String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public final void print() {
            System.out.println(this.name);
        }
        @Override
        public void hello() {
            System.out.println("hello method" + this.name);
        }
    }
    
    • jdk代理类
    public class JdkProxy implements InvocationHandler {
        /**
         * 被代理的类
         */
        private Class target;
        /**
         * 被代理的对象
         */
        private Object targetProxy;
        public JdkProxy(Class<?> targetClass) {
            try {
                this.target = targetClass;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        public Object createProxy(String name) {
            try {
                this.targetProxy = target.getConstructor(new Class[]{String.class}).newInstance(new Object[]{name});
            } catch (Exception e) {
                e.printStackTrace();
            }
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.target.getInterfaces(), this);
        }
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println(method.getName());
            return method.invoke(targetProxy, args);
        }
    }
    

    cglib实现动态代理

    核心

    • 代理类必须实现 MethodInterceptor 接口
    • 只能代理非final的方法

    cglib实现的代理类

    public class CglibProxy implements MethodInterceptor {
    
        private Class<?> target;
    
        public CglibProxy(Class<?> target) {
            this.target = target;
        }
    
        Object createProxy(String name) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.target);
            enhancer.setCallback(this);
            Object[] args = new String[]{name};
            Class[] classes = new Class[]{String.class};
            return enhancer.create(classes, args);
        }
    
        /**
         * 在拦截器这个方法中可以实现aop
         * 只是会拦截非final class, 非final的method
         * cglib 无法代理final的方法
         *
         * @param var1 需要代理的对象
         * @param var2 被代理的方法
         * @param var3 参数
         * @param var4 代理方法
         * @return
         * @throws Throwable
         */
        public Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable {
            // 对方法进行拦截
            System.out.println(var2.getName());
            return var4.invokeSuper(var1, var3);
        }
    
    }
    

    测试类

    public class Reflect {
        public static void main(String args[]) {
            //cg 动态代理
            CglibProxy proxy = new CglibProxy(Service.class);
            Service service = (Service) proxy.createProxy("CglibProxy");
            service.setName("CglibProxy");
            System.out.println(service.getName());
            // 不能代理final的方法
            service.print();
            service.hello();
            System.out.println("------jdk");
            // jdk 动态代理
            Reflect.JdkProxy jdkPorxy = new Reflect.JdkProxy(Service.class);
            jdkService service1 = (jdkService) jdkPorxy.createProxy("JdkProxy");
            service1.hello();
        }
    }
    

    相关文章

      网友评论

          本文标题:java 动态代理 jdk和cglib

          本文链接:https://www.haomeiwen.com/subject/tghxwqtx.html