代理模式是一种常用的设计模式,当要实现实际的业务逻辑时,我们不直接调用,而是借用中介,他帮我们将要做的事情做好,而且还能体现出高扩展性,比如我们想要新增一些日志的时候,底层的业务逻辑我们是不用动的,将这部分活交给中介就行了,告诉他处理那一部分逻辑的记录怎样的日志。
优点:
(1).职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
先看静态代理模式:
真正处理业务的人和代理同时实现同一个接口,但是在真正的逻辑处理是在处理业务的人的继承自接口的方法中实现,而代理的对于接口的方法的重载其实还是用真正处理业务的人来实现的,只是在这个方法中处理的方法不变,我们可以新增一些逻辑,比如记录日志等;
接口:
public interface Sevice {
public void doSome();
public String doAnother();
}
处理业务的人:
public class ServiceImp implements Sevice{
public ServiceImp() {
}
@Override
public void doSome() {
System.out.println("我才是真正的处理逻辑的人");
}
//子类的新增方法
public String doAnother(){
return "新方法的返回值";
}
}
静态代理;
public class ServiceProxy implements Sevice {
Sevice sevice;
public ServiceProxy(Sevice sevice) {
this.sevice = sevice;
}
@Override
public void doSome() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
System.out.println("执行方法前"+df.format(new Date()));// new Date()为获取当前系统时间
sevice.doSome();
}
@Override
public String doAnother() {
return null;
}
}
测试:
@org.junit.Test
public void Test2(){
Sevice sevice=new ServiceImp();
ServiceProxy serviceProxy=new ServiceProxy(sevice);
serviceProxy.doSome();
}
--------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------动态代理--------------------------------------------------------------
静态代理是在doSome方法上加了记录日志的信息,我想要在每一个方法上都有记录,这就需要使用动态代理。
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
//返回的就是需要代理的方法的返回值
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理的方法执行前");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/
System.out.println("执行方法前"+df.format(new Date()));
Object invoke = method.invoke(object, args);
System.out.println(invoke);
return invoke;
}
}
测试:
@org.junit.Test
public void Test3(){
DynamicProxy proxy=new DynamicProxy(new ServiceImp());
Sevice sevice = (Sevice) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{Sevice.class}, proxy);
// sevice.doSome();
sevice.doAnother();
}
分析一下:增加代理的主要部分
创建 InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
使用Proxy的静态方法,创建代理对象。并把返回值类型转为接口类型
反射中调用方法:
通过Method可以执行某个目标类的方法,Method.invoke(目标对象,方法参数);