zoukankan      html  css  js  c++  java
  • 代理模式

    代理模式(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();
        }
    }
  • 相关阅读:
    10-12
    8-10
    5.2-5.3
    四则运算 测试与封装
    第5-7章
    汉堡包
    1-5章
    实验二
    实验一
    Controller方法是如何与请求匹配上的及参数如何填充的
  • 原文地址:https://www.cnblogs.com/StanLong/p/6782690.html
Copyright © 2011-2022 走看看