• 代理模式


    代理模式(Proxy)是一种设计模式,它提供了对目标对象另外的访问方式。即通过代理访问目标对象。可以在目标对象实现的基础上增加额外的功能操作(扩展目标对象的功能)

    1、静态代理:代理对象要实现与目标对象一样的接口

    示例:(1)接口

    public interface IUserDao {
        public void save();
    }

    (2)目标对象

    public class UserDao implements IUserDao {
    
        @Override
        public void save() {
            System.out.println("模拟保存用户数据到数据库");
        }
    
    }

    (3)代理对象

    public class UserDaoProxy implements IUserDao { //代理对象要与目标对象实现一样的接口
        
        //通过构造方法接收保存目标对象
        private IUserDao userDao;
        public UserDaoProxy(IUserDao userDao){
            this.userDao = userDao;
        }
    
        @Override
        public void save() {
            System.out.println("开始事务");
            userDao.save();
            System.out.println("结束事务");
    
        }
    
    }

    (4)测试代理

    public class TestProxy {
        
        public static void main(String[] ages){
            IUserDao userDao = new UserDao();
            IUserDao proxy = new UserDaoProxy(userDao);
            proxy.save();
        }
    
    }

    静态代理:优:可以做到在不修改目标对象功能的前提下扩展目标对象的功能。 缺:因为代理对象需要与目标对象实现一样的接口所以会有很多的代理类,一旦接口增加方法目标对象与代理对象都要维护。

    动态代理

    代理对象不需要实现接口,代理对象的生成是动态的,利用JDK的API动态的在内存中构建代理对象。需要我们指定创建代理对象实现的接口类型。动态代理也以叫做API代理,接口代理。

    示例:(1)接口

    public interface IUserDao {
        public void save();
    }

    (2)目标对象

    public class UserDao implements IUserDao {
    
        @Override
        public void save() {
            System.out.println("模拟保存用户数据到数据库");
        }
    
    }

    (3)动态代理对象

    public class ProxyFactory {
        
        public Object target; //目标对象
        public ProxyFactory(Object target){
            this.target = target;
        }
        
        //对目标对象生成代理对象
        public Object getProxyInstance(){
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(), //目标对象的类加载器
                    target.getClass().getInterfaces(), //目标对象实现的接口类型
                    new InvocationHandler() { //事件处理器
                        
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("开始事务");
                            Object returnValue = method.invoke(target, args); //调用目标对象的方法
                            System.out.println("结束事务");
                            return returnValue;
                        }
                    });
        }
    }

    (4)测试动态代理

    public class TestProxy {
        
        public static void main(String[] ages){
            
            //目标对象
            IUserDao userDao = new UserDao();
            
            //给目标对象创建代理对象
            IUserDao proxy = (IUserDao)new ProxyFactory(userDao).getProxyInstance();
            
            //执行代理对象方法
            proxy.save();
        }
    
    }

     cglib子类代理

    1)需要引入cglib.jar文件,spring的核心包spring-core也包括了cglib功能,直接引入spring核心包也可

    2)代理的类不能用final修饰,否则会报错

    3)目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法

    (1)目标对象

    public class UserDao {
        public void save() {
            System.out.println("模拟保存用户数据到数据库");
        }
    }

    (2)cglib代理对象(这里使用的是spring核心包)

    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    public class CglibProxy implements MethodInterceptor{
        
        //维护目标对象
        private Object target;
        public CglibProxy(Object target){
            this.target = target;
        }
    
        //给目标对象创建代理对象
        public Object getProxyInstance(){
            //1、工具类
            Enhancer en = new Enhancer();
            
            //2、设置父类
            en.setSuperclass(target.getClass());
            
            //3、设置回调函数
            en.setCallback(this);
            
            //4、创建子类(代理对象)
            return en.create();
        }
        
        @Override
        public Object intercept(Object object
                , Method method, Object[] args
                , MethodProxy proxy) throws Throwable {
            System.out.println("开始事务");
            //执行目标对象的方法
            Object returnValue = method.invoke(target, args);
            
            System.out.println("提交事务");
            
            return returnValue;
        }

    (3)、测试cglib代理

    public class test {
    
        @Test
        public void testCglib(){
            UserDao target = new UserDao();
            
            UserDao proxy =(UserDao)new CglibProxy(target).getProxyInstance();
            
            proxy.save();
        }
    }
  • 相关阅读:
    组合算法问题
    递归之全排列问题
    递归之整数划分问题
    利用Python完成一个小游戏:随机挑选一个单词,并对其进行乱序,玩家要猜出原始单词
    对数组元素进行排序的方法总结(利用C++)
    用c++语言编写函数 int index(char *s,char * t),返回字符串t在字符串s中出现的最左边的位置,如果s中没有与t匹配的子串,则返回-1。类似于索引的功能。
    用MFC完成一个简单的猜数字游戏: 输入的四位数中,位置和数字都正确为A,数字相同而位置不同的为B。
    用Matlab完成:从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
    利用matlab实现以下功能:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
    白书_倒三角形_C语言描述
  • 原文地址:https://www.cnblogs.com/StanLong/p/6782690.html
Copyright © 2020-2023  润新知