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

 

转载于:https://www.cnblogs.com/lj95801/p/5392689.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值