zoukankan      html  css  js  c++  java
  • 6、动态代理

    在前面讲静态代理的时候说道它有一个缺陷:必须为每一个你想要进行代理的接口都设计一个静态的代理类。

    那么,有没有一种更加灵活的方案呢?这就是动态代理,即在运行时为特定接口动态的生成一个代理类对象。

    与动态代理密切相关的有两个东西:java.lang.reflect.InvocationHandler与java.lang.reflect.Proxy

    实现一个动态代理只需要做两个步骤的工作:①设计一个Handler类让其实现InvocationHandler接口;②调用Proxy.newProxyInstance(...)方法来得到一个代理类对象;

    第一步:

    package com.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.util.Date;
    
    public class RequestProxyHandler implements InvocationHandler {
        
        private Object proxied;
        public RequestProxyHandler(Object proxied) {
            this.proxied = proxied;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            
            //针对request方法作特殊处理:如果请求的当前时间在00:00:00~05:59:59之间,则不会执行实际的reques(...)方法
            if(method.getName().equals("request")){
                Date start = new Date(DateUtil.timeOfToday(0, 0, 0));
                Date end = new Date(DateUtil.timeOfToday(5, 59, 59));
                Date now = new Date();
                if(now.after(start)&&now.before(end)){
                    System.out.println("系统维护时间,禁止请求...");
                    return null;    //不会执行被代理对象的实际方法
                }
            }
            //使用反射来调用被代理的实际方法
            return method.invoke(proxied, args);    
        }
    }

    第二步:

     1 package com.proxy;
     2 
     3 import java.lang.reflect.Proxy;
     4 
     5 public class Test {
     6     
     7     public static void main(String[] args) {
     8         //创建一个被代理对象
     9         ISubject subProxied = new SubjectImpl();
    10         //将被代理对象传递到MyProxyHandler中,创建一个InvocationHandler对象来处理被代理对象
    11         ISubject sub = (ISubject) Proxy.newProxyInstance(SubjectImpl.class.getClassLoader(),
    12                 new Class[]{ISubject.class}, new RequestProxyHandler(subProxied));
    13         
    14         sub.request();
    15         int res = (int)sub.add(10, 20);
    16         System.out.println(res);
    17     }
    18 
    19 }

    下面是完整的代码:

     1 package com.proxy;
     2 
     3 import java.util.Calendar;
     4 import java.util.Date;
     5 
     6 public class DateUtil {
     7     
     8     public static long timeOfToday(int hour, int minute, int second){
     9         Calendar calendar = Calendar.getInstance();
    10         calendar.set(Calendar.HOUR_OF_DAY, hour);
    11         calendar.set(Calendar.MINUTE, minute);
    12         calendar.set(Calendar.SECOND, second);
    13         calendar.set(Calendar.MILLISECOND, 0);
    14         Date today = calendar.getTime();
    15         return today.getTime();
    16     }
    17 }
    public class DateUtil
    package com.proxy;
    
    public interface ISubject {
        
        public void request();
        public int add(int a, int b);
    
    }
    public interface ISubject
     1 package com.proxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.util.Date;
     6 
     7 public class RequestProxyHandler implements InvocationHandler {
     8     
     9     private Object proxied;
    10     public RequestProxyHandler(Object proxied) {
    11         this.proxied = proxied;
    12     }
    13 
    14     @Override
    15     public Object invoke(Object proxy, Method method, Object[] args)
    16             throws Throwable {
    17         
    18         //针对request方法作特殊处理:如果请求的当前时间在00:00:00~05:59:59之间,则不会执行实际的reques(...)方法
    19         if(method.getName().equals("request")){
    20             Date start = new Date(DateUtil.timeOfToday(0, 0, 0));
    21             Date end = new Date(DateUtil.timeOfToday(5, 59, 59));
    22             Date now = new Date();
    23             if(now.after(start)&&now.before(end)){
    24                 System.out.println("系统维护时间,禁止请求...");
    25                 return null;    //不会执行被代理对象的实际方法
    26             }
    27         }
    28         //使用反射来调用被代理的实际方法
    29         return method.invoke(proxied, args);    
    30     }
    31 }
    public class RequestProxyHandler implements InvocationHandler
     1 package com.proxy;
     2 
     3 public class SubjectImpl implements ISubject {
     4 
     5     @Override
     6     public void request() {
     7         System.out.println("发送请求...");
     8     }
     9 
    10     @Override
    11     public int add(int a, int b) {
    12         return a + b;
    13     }
    14 
    15 }
    public class SubjectImpl implements ISubject
     1 package com.proxy;
     2 
     3 import java.lang.reflect.Proxy;
     4 
     5 public class Test {
     6     
     7     public static void main(String[] args) {
     8         //创建一个被代理对象
     9         ISubject subProxied = new SubjectImpl();
    10         //将被代理对象传递到MyProxyHandler中,创建一个InvocationHandler对象来处理被代理对象
    11         ISubject sub = (ISubject) Proxy.newProxyInstance(SubjectImpl.class.getClassLoader(),
    12                 new Class[]{ISubject.class}, new RequestProxyHandler(subProxied));
    13         
    14         sub.request();
    15         int res = (int)sub.add(10, 20);
    16         System.out.println(res);
    17     }
    18 
    19 }
    public class Test
  • 相关阅读:
    CodeForces 156B Suspects(枚举)
    CodeForces 156A Message(暴力)
    CodeForces 157B Trace
    CodeForces 157A Game Outcome
    HDU 3578 Greedy Tino(双塔DP)
    POJ 2609 Ferry Loading(双塔DP)
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛 19000互质的个数
    Java 第十一届 蓝桥杯 省模拟赛十六进制转换成十进制
  • 原文地址:https://www.cnblogs.com/lj95801/p/5392689.html
Copyright © 2011-2022 走看看