观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

前言

  为其他对象提供一种代理以控制对象对这个对象的访问。

使用场景

 当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。

静态代理

接口

public interface IInfoService {
    void setInfo();
}

操作

public class InfoDao implements IInfoService {

    @Override
    public void setInfo() {
        Log.e("调试_临时_log", "设置数据中");
    }
}

代理

public class InfoDaoProxy implements IInfoService {
    private IInfoService iInfoService;

    public InfoDaoProxy(IInfoService service){
        this.iInfoService = service;

    }

    @Override
    public void setInfo() {
        Log.e("调试_临时_log", "this_马上设置");
        iInfoService.setInfo();
        Log.e("调试_临时_log", "this_设置完成");
    }
}

调用

        InfoDao dao = new InfoDao();
        new InfoDaoProxy(dao).setInfo();

结果:

2021-11-27 15:03:23.962 30942-30942/com.example.myapplication E/调试_临时_log: this_马上设置
2021-11-27 15:03:23.962 30942-30942/com.example.myapplication E/调试_临时_log: 设置数据中
2021-11-27 15:03:23.962 30942-30942/com.example.myapplication E/调试_临时_log: this_设置完成

 

 

动态代理

动态代理有以下特点:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理

JDK中生成代理对象的API
代理类所在包:java.lang.reflect.Proxy
JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数,完整的写法是:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )

注意该方法是在Proxy类中是静态方法,且接收的三个参数依次为:

  • ClassLoader loader,:指定当前目标对象使用类加载器,获取加载器的方法是固定的
  • Class<?>[] interfaces,:目标对象实现的接口的类型,使用泛型方式确认类型
  • InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入

 

注解

@Documented
@Target(METHOD)
@Retention(RUNTIME)
@interface Info {
    String name() default "";
    int id() default 0;
}

接口

public interface IInfoService {
    @Info(name = "小明", id = 1)
    Call setInfo(Boolean sex);
}

返回操作类

public class Call {
    private List<Object> valueList;

    protected Call(List<Object> list) {
        valueList = list;
    }

    public String execute(){
        if (valueList == null || valueList.size() == 0){
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (Object o : valueList){
            if (o instanceof String){
                stringBuilder.append(o);

            }else if (o instanceof Integer){
                stringBuilder.append(o);

            }else if (o instanceof Long){
                stringBuilder.append(o);

            }else if (o instanceof Boolean){
                stringBuilder.append(o);

            }else if (o instanceof Float){
                stringBuilder.append(o);

            }else if (o instanceof Double){
                stringBuilder.append(o);

            }
        }
        return stringBuilder.toString();
    }
}

代理

public class InfoDaoProxy {


    public static <T> T create(Class<T> service){
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getDeclaringClass() == Object.class) {
                    return method.invoke(this, args);
                }
                List<Object> objects = new ArrayList<>();
                Info info = method.getAnnotation(Info.class);
                objects.add(info.name());
                objects.add(info.id());
                if (args != null){
                    for (Object o : args){
                        objects.add(o);
                    }

                }
                return new Call(objects);
            }
        });
    }
}

 

 

 

End

posted on 2020-12-01 21:05  观心静  阅读(116)  评论(0编辑  收藏  举报