设计模式---代理模式

转载:

// 委托接口
public interface IHelloService {
    /**
     * 定义接口方法
     * @param userName
     * @return
     */
    String sayHello(String userName);
}

// 委托类实现
public class HelloService implements IHelloService {
    @Override
    public String sayHello(String userName) {
      return "HelloService" + userName;
    }
}

// 代理类
public class StaticProxyHello implements IHelloService {
    private IHelloService helloService = new HelloService();
    @Override
    public String sayHello(String userName) {
        /** 代理对象可以在此处包装一下*/
        System.out.println("代理对象包装礼盒...");
        return helloService.sayHello(userName);
    }
}
// 测试静态代理类
public class MainStatic {
    public static void main(String[] args) {
        StaticProxyHello staticProxyHello = new StaticProxyHello();
        staticProxyHello.sayHello("isole");
    }
}

Java代理模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// 委托接口
public interface IHelloService {
    /**
     * 定义接口方法
     * @param userName
     * @return
     */
    String sayHello(String userName);
}
// 委托类实现
public class HelloService implements IHelloService {

    @Override
    public String sayHello(String userName) {
        System.out.println("helloService" + userName);
        return "HelloService" + userName;
    }
}

// 代理类
public class StaticProxyHello implements IHelloService {
    private IHelloService helloService = new HelloService();
    @Override
    public String sayHello(String userName) {
        /** 代理对象可以在此处包装一下*/
        System.out.println("代理对象包装礼盒...");
        return helloService.sayHello(userName);
    }
}
// 测试静态代理类
public class MainStatic {
    public static void main(String[] args) {
        StaticProxyHello staticProxyHello = new StaticProxyHello();
        staticProxyHello.sayHello("isole");
    }
}

在这里插入图片描述
在这里插入图片描述

public interface InvocationHandler {
    /**
     * 调用处理
     * @param proxy 代理类对象
     * @param methon 标识具体调用的是代理类的哪个方法
     * @param args 代理类方法的参数
     */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

在这里插入图片描述

// 委托类接口
public interface IHelloService {
    /**
     * 方法1
     * @param userName
     * @return
     */
    String sayHello(String userName);

    /**
     * 方法2
     * @param userName
     * @return
     */
    String sayByeBye(String userName);
    }

// 委托类
public class HelloService implements IHelloService {
    @Override
    public String sayHello(String userName) {
        System.out.println(userName + " hello");
        return userName + " hello";
    }

    @Override
    public String sayByeBye(String userName) {
        System.out.println(userName + " ByeBye");
        return userName + " ByeBye";
    }
}

// 中间类
public class JavaProxyInvocationHandler implements InvocationHandler {
    /**
     * 中间类持有委托类对象的引用,这里会构成一种静态代理关系
     */
    private Object obj ;

    /**
     * 有参构造器,传入委托类的对象
     * @param obj 委托类的对象
     */
    public JavaProxyInvocationHandler(Object obj){
        this.obj = obj;
    }

    /**
     * 动态生成代理类对象,Proxy.newProxyInstance
     * @return 返回代理类的实例
     */
    public Object newProxyInstance() {
        return Proxy.newProxyInstance(
                //指定代理对象的类加载器
                obj.getClass().getClassLoader(),
                //代理对象需要实现的接口,可以同时指定多个接口
                obj.getClass().getInterfaces(),
                //方法调用的实际处理者,代理对象的方法调用都会转发到这里
                this);
    }


    /**
     *
     * @param proxy 代理对象
     * @param method 代理方法
     * @param args 方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke before");
        Object result = method.invoke(obj, args);
        System.out.println("invoke after");
        return result;
    }
}

// 测试动态代理类
public class MainJavaProxy {
    public static void main(String[] args) {
        JavaProxyInvocationHandler proxyInvocationHandler = new JavaProxyInvocationHandler(new HelloService());
        IHelloService helloService = (IHelloService) proxyInvocationHandler.newProxyInstance();
        helloService.sayByeBye("paopao");
        helloService.sayHello("yupao");
    }
}

在这里插入图片描述

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        // 检查空指针
        Objects.requireNonNull(h);
        // 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
        final Class<?>[] intfs = interfaces.clone();
        // 获取系统的安全接口,不为空的话需要验证是否允许访问这种关系的代理访问
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * 生成代理类 Class,通过类加载器和接口
         */
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * 通过构造器来创建实例
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            //获取所有的构造器
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            // 构造器不是public的话需要设置可以访问
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            // 返回创建的代理类Class的实例对象
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

在这里插入图片描述

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2</version>
</dependency>

在这里插入图片描述

// 委托类,是一个简单类
public class CglibHelloClass {
   /**
    * 方法1
    * @param userName
    * @return
    */
   public String sayHello(String userName){
       System.out.println("目标对象的方法执行了");
       return userName + " sayHello";
   }

   public String sayByeBye(String userName){
       System.out.println("目标对象的方法执行了");
       return userName + " sayByeBye";
   }

}
/**
* CglibInterceptor 用于对方法调用拦截以及回调
*
*/
public class CglibInterceptor implements MethodInterceptor {
   /**
    * CGLIB 增强类对象,代理类对象是由 Enhancer 类创建的,
    * Enhancer 是 CGLIB 的字节码增强器,可以很方便的对类进行拓展
    */
   private Enhancer enhancer = new Enhancer();

   /**
    *
    * @param obj  被代理的对象
    * @param method 代理的方法
    * @param args 方法的参数
    * @param proxy CGLIB方法代理对象
    * @return  cglib生成用来代替Method对象的一个对象,使用MethodProxy比调用JDK自身的Method直接执行方法效率会有提升
    * @throws Throwable
    */
   @Override
   public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
       System.out.println("方法调用之前");
       Object o = proxy.invokeSuper(obj, args);
       System.out.println("方法调用之后");
       return o;
   }


   /**
    * 使用动态代理创建一个代理对象
    * @param c
    * @return
    */
   public  Object newProxyInstance(Class<?> c) {
       /**
        * 设置产生的代理对象的父类,增强类型
        */
       enhancer.setSuperclass(c);
       /**
        * 定义代理逻辑对象为当前对象,要求当前对象实现 MethodInterceptor 接口
        */
       enhancer.setCallback(this);
       /**
        * 使用默认无参数的构造函数创建目标对象,这是一个前提,被代理的类要提供无参构造方法
        */
       return enhancer.create();
   }
}

//测试类
public class MainCglibProxy {
   public static void main(String[] args) {
       CglibProxy cglibProxy = new CglibProxy();
       CglibHelloClass cglibHelloClass = (CglibHelloClass) cglibProxy.newProxyInstance(CglibHelloClass.class);
       cglibHelloClass.sayHello("isole");
       cglibHelloClass.sayByeBye("sss");
   }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值