zoukankan      html  css  js  c++  java
  • java的静态代理,jdk代理和cglib代理例子

    一:静态代理

      在使用静态代理时,需要定义接口或者父类。被代理对象(目标对象)和代理对象都需要实现同一接口或者继承父类。

      使用步骤:

      1:定义一个接口IStudentDao

      2:被代理对象(目标对象)StudentDao实现接口

      3:代理对象StudentDaoProxy也需要实现接口

      4:代理对象调用被代理对象方法

      具体实现:

      IStudentDao
    public interface IStudentDao {
        void study();
    }
    

       StudentDao

    public class StudentDao  implements IStudentDao{
        @Override
        public void study() {
            System.out.println("小明正在学习中...");
        }
    }
    

      StudentDaoProxy

    public class StudentDaoProxy implements IStudentDao {
        private IStudentDao stu;//被代理对象,通过接口依赖
    
        public StudentDaoProxy(IStudentDao stu) {
            this.stu = stu;
        }
    
        @Override
        public void study() {
            System.out.println("被代理对象方法执行前..."); //这里可以写一些增强方法
            stu.study();
            System.out.println("被代理对象方法执行后...");
        }
    }
    

      Client

    public class Main {
    
        public static void main(String[] args) throws IllegalAccessException, InstantiationException {
           // IStudentDao stu = new StudentDao();//代理对象
            IStudentDao proxyStu = new StudentDaoProxy(StudentDao.class.newInstance());//代理对象
            proxyStu.study();
        }
    }
    

     运行结果:

     二:JDK动态代理

      jdk动态代理是代理模式实现的一种方法。也是需要实现接口的。主要是通过反射来动态生成代理类。被代理对象需要实现接口,代理对象不需要实现接口;

      生成代理对象的JDK API:

    /**
    *loader:类加载器
    *interfaces:被代理类实现的接口
    *h:重写invocationHandler中的invoke,
    *return:返回一个代理对象
    */
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
            throws IllegalArgumentException
    

      IStudentDao:

    public interface IStudentDao {
    
        void study();
    
    }
    

      StudentDao

    public class StudentDao implements IStudentDao {
        @Override
        public void study() {
            System.out.println("小明正在学习......");
        }
    }
    

      ProxyFactory:

    //实现InvocationHandler接口,重写invoke方法
    public class ProxyFactory implements InvocationHandler{
    
        private Object target;//被代理的对象;
    
        public ProxyFactory(Object target) {
            this.target = target;
        }
    
        //返回一个代理对象
        public Object getProxyInstance()
        {
    
    
    
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    this
            );
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("jdk代理开始");
            Object invoke = method.invoke(target, args);
    
            System.out.println("jdk代理结束");
    
            return invoke;
        }
    }
    

      测试:

    public class Main {
    
    
        public static void main(String[] args) throws IllegalAccessException, InstantiationException {
            IStudentDao stu = new StudentDao();
            IStudentDao instance = (IStudentDao)new ProxyFactory(stu).getProxyInstance();
            instance.study();
        }
    }

      结果:

     三:cglib实现动态代理

      无论是静态代理或者是jdk动态代理都需要实现一个接口。有时候我们只有一个对象,没有实现任何接口的。这时候可以使用目标对象子类来实现动态代理。cglib代理

    通过在内存中构建子类从而实现对目标对象方法的扩建。

      先导入依赖:

    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.8</version>
            </dependency>
    

      StudentDao

    public class StudentDao {
    
        public void study()
        {
            System.out.println("小明正在学习......");
        }
    }
    

      ProxyFactory

    public class ProxyFactory  implements MethodInterceptor {
    
        private Object target;
    
        public ProxyFactory(Object target) {
            this.target = target;
        }
    
    
        public Object getProxyInstance()
        {
            //1.创建一个工具类
            Enhancer enhancer = new Enhancer();
            //2.设置父类
            enhancer.setSuperclass(target.getClass());
            //3.设置回调函数
            enhancer.setCallback(this);
            //4.创建子类,即代理对象
            return enhancer.create();
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("cglib代理开始");
            Object res = method.invoke(target, objects);
            System.out.println("cglib代理结束");
    
            return res;
        }
    }
    

      Main

    public class Main {
    
        public static void main(String[] args) throws IllegalAccessException, InstantiationException {
            ProxyFactory proxyFactory = new ProxyFactory(StudentDao.class.newInstance());
            StudentDao instance = (StudentDao)proxyFactory.getProxyInstance();
            instance.study();
    
        }
    }
    

      

     四:总结

    1:静态代理和jdk动态代理都需要实现接口,而cglib不用实现接口。
    2:代理模式可以在不修改被代理对象(目标对象)的前提下,对目标对象进行扩展。
    3:静态代理每次修改接口都需要维护目标对象和被代理对象。
    4:你所热爱的,就是你的生活。

      

     

     

     

  • 相关阅读:
    CacheHelper
    自动完成 或者动态匹配
    http://www.jb51.net/article/28619.htm
    http://www.kindsoft.net/docs/qna.html
    开发测试的理想模型
    关于浮点数的死区问题
    ZOJ Problem Set – 2321 Filling Out the Team
    Input类、四元数、
    忙蒙蔽了
    2014-03-28
  • 原文地址:https://www.cnblogs.com/swqblog/p/12843524.html
Copyright © 2011-2022 走看看