java代理模式实现
@(代理模式)[静态代理,动态代理,InvocationHandler]
java的代理模式 分为两种,静态代理和动态代理,学习下什么是代理和静态动态代理的作用。
代理
什么是代理?代理就像中介,房东想租房,所以房东有租房这个方法,想委托给中介帮忙租出去,所以中介就是房东的代理也有租房这个方法,但是那中介除了租房之外可能还有其他操作,比如租房前签合同,租房后收中介费,这些和房东都没有关系。
静态代理
先来看看静态代理的实现
需要准备三个文件
1、抽象接口
2、实际实现类
3、代理类
4、测试类
静态代理实现
1、抽象接口 Subject
定义实现类和代理类的公共方法(或叫公共动作,类似于租房动作)
package com.proxy;
/**
* @Author: YLBG-YCY-1325
* @Description:
* @Date: 2017/8/14
*/
public interface Subject {
void doSomething();
}
2、定义实现类 (RealSubjct)
这个是实际的源实现类(类似于房东的角色)
package com.proxy;
/**
* @Author: YLBG-YCY-1325
* @Description:
* @Date: 2017/8/14
*/
public class RealSubject implements Subject{
@Override
public void doSomething() {
System.out.println("代理....");
}
}
3、代理类(SubjectProxy)
受RealSubject委托的类(类似于中介的角色),在SubjectProxy类中定义实际实现类(RealSubject)的实例,在做同样动作的时候,代理类可以在前后多做一些逻辑操作(逻辑操作也可以是其他的方法)。
package com.proxy;
/**
* @Author: YLBG-YCY-1325
* @Description:
* @Date: 2017/8/14
*/
public class SubjectProxy implements Subject{
private Subject subject = new RealSubject();
@Override
public void doSomething() {
System.out.println("在doSomething之前的逻辑");
subject.doSomething();
System.out.println("在doSomething之后的逻辑");
}
}
4、测试类
package com.proxy;
/**
* @Author: YLBG-YCY-1325
* @Description:
* @Date: 2017/8/14
*/
public class ProxyTest {
public static void main(String[] args) {
SubjectProxy staticSubjectProxy = new SubjectProxy();
staticSubjectProxy.doSomething();
System.out.println("------------------动态代理-------------");
Subject realSubject = new RealSubject();
SubjectHandler subjectHandler = new SubjectHandler(realSubject);
Subject subjectProxy = (Subject) subjectHandler.getProxy();
subjectProxy.doSomething();
}
}
代理的意义在于在操作的实际实现类的方法的同时能做一些其他的逻辑(类似于Spring 的 AOP,不过Spring的AOP是动态代理)。
动态代理
动态代理的实现准备了四个文件
1、抽象接口
2、实际实现类
3、调用处理器
4、测试类
抽象接口、实际实现类用原来的就行了;
动态代理实现
实现调用处理器:
package com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author: YLBG-YCY-1325
* @Description:
* @Date: 2017/8/14
*/
public class SubjectHandler implements InvocationHandler {
private Object target;
public SubjectHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
/**
* 获取目标代理对象
* @return
*/
public Object getProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
}
SubjectHandler(Object target) :传入目标类(实际实现类,要委托的类)
invoke(Object proxy, Method method, Object[] args):代理类方法执行
getProxy():获取代理类
具体的实现原理可以参考:JDK动态代理原理探究
测试类:
package com.proxy;
/**
* @Author: YLBG-YCY-1325
* @Description:
* @Date: 2017/8/14
*/
public class ProxyTest {
public static void main(String[] args) {
SubjectProxy staticSubjectProxy = new SubjectProxy();
staticSubjectProxy.doSomething();
System.out.println("------------------动态代理-------------");
Subject realSubject = new RealSubject();
SubjectHandler subjectHandler = new SubjectHandler(realSubject);
Subject subjectProxy = (Subject) subjectHandler.getProxy();
subjectProxy.doSomething();
}
}
动态代理的意义
动态代理的意义在于动态生成代理类,不用每次都写新的代理类;例如:我们又有新的需求,要写一个新的接口和新的实现类,而这个实现类的方法在执行之前也要做System.out.println(“在doSomething之前的逻辑”) 和 System.out.println(“在doSomething之后的逻辑”) (这两块逻辑是自己定义的逻辑,我这边是上面静态代理上的逻辑)那怎么办?重新写一个代理类呗。是啊,如果是一两个还好,如果有100个需求都要用到那两块逻辑那?爆炸,对不起项目经理我完成不了这个需求,项目经理:用动态代理啊你这个傻缺。所以这就是动态代理的意义,需要处理的逻辑是定死的,你有新的需求每个需求都要用到同用的两块逻辑,OK,动态代理动态生成代理类,完美。
其他
从知乎上接下来了一张图片,总结的非常好,链接地址是:Java 动态代理作用是什么?
图片是: