zoukankan      html  css  js  c++  java
  • Spring之代理模式实例

    1、静态代理

    2、JDK动态代理

    JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口,其核心是InvocationHandler接口和Proxy类。 

    jdk动态代理之所以只能代理接口是因为代理类本身已经extends了Proxy,而java是不允许多重继承的,但是允许实现多个接口,因此才有cglib的需要吧。

    public interface Math {
        public int div(int a, int b) throws Exception;
    }
    
    @Component
    public class MathCaculator implements Math {
        public MathCaculator() {
            System.out.println("MathCaculator构造器***************");
        }
        public int div(int a, int b) throws Exception {
            System.out.println("除法的方法主体");
            return a/b;
        }
    }
    
    public class DynamicProxy implements InvocationHandler {
        Object targetObject;
    
        public Object getProxyObejct(Object targetObject) {
            this.targetObject = targetObject;
            return Proxy.newProxyInstance(targetObject.getClass().getClassLoader()
                    ,targetObject.getClass().getInterfaces(),this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            long startTime = System.currentTimeMillis();
            Thread.sleep(100);
            Object result=method.invoke(targetObject, args);
            long endTime = System.currentTimeMillis();
            System.out.println("耗时"+(endTime-startTime)+"秒");
            System.out.println("结果+"+result);
            return result;
        }
    }
    
    
    public class Test {
        public static void main(String[] args) throws Exception {
            Math math = (Math) new DynamicProxy().getProxyObejct(new MathCaculator());
            math.div(10,5);
        }
    }
    

    3、CGLIB动态代理 

     对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

    如果目标类没有实现接口,那就要选择使用CGLIB来动态代理目标类。CGLIB是通过继承的方式做的动态代理,因此,如果某个类被标记为final,那么它是无法使用CGLIB做动态代理。CGLIB会使生成的代理类继承当前的对象,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。

    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class CglibDynamicProxy implements MethodInterceptor {
        Object targetObject;
    
        public Object getProxyObject(Object object){
            System.out.println("cglib创建代理");
            this.targetObject = object;
            Enhancer enhancer = new Enhancer();
            enhancer.setCallback(this);
            enhancer.setSuperclass(targetObject.getClass());
            return enhancer.create();
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            long startTime = System.currentTimeMillis();
            Thread.sleep(100);
            Object result=methodProxy.invoke(targetObject, args);
            long endTime = System.currentTimeMillis();
            System.out.println("耗时"+(endTime-startTime)+"秒");
            System.out.println("结果+"+result);
            return result;
        }
    }
    

      

  • 相关阅读:
    UIFont的使用和字体类型总结
    LOJ-10100(割点个数)
    LOJ-10099(点双联通)
    poj-3177(并查集+双联通分量+Tarjan算法)
    图论:割点和桥
    牛客训练五:炫酷数学(思维)
    牛客训练五:炫酷路途(c++与dp)
    并查集的两种实现(按秩合并+路径压缩)
    牛客训练六:海啸(二维树状数组+vector函数的使用)
    牛客训练六:美食(贪心)
  • 原文地址:https://www.cnblogs.com/yaohuiqin/p/10488853.html
Copyright © 2011-2022 走看看