java动态链模式和责任链模式
很多框架的技术原理都涉及到java动态链模式和责任链模式,比如spring和mybatis。
动态代理模式
代理,顾名思义,代为处理。先来看看名词解释:
代理就是定义一个行为和某类(class)的对象相似,而又潜在地表示了所有继承自该类的对象的东西,我们把这种类的对象叫做代理(surrogate)
来源代理(百度百科)。
来看一下最常用的代理技术:
- JDK代理技术(JDK自带代理技术)
- CGLIB代理技术(第三方代理技术)
JDK代理技术
jdk代理技术是java.lang.reflect
包提供的方式,它必须通过一个接口才能产生代理对象,所以必须先创建对象,所以先对接口进行定义。
public interface HelloWorld{
void sayHelloWorld();
}
然后我们来创建一个是实现类:
public class HelloWorldImpl implements HelloWorld{
@override
public void sayHelloWorld(){
System.out.println("Hello World!");
}
}
实现动态代理,分成两步走,第一步,实现接口java.lang.reflect.InvocationHandler
,它有一个invoke方法,用于提供接口数组用于下挂代理对象
public class JdkProxyExample implements InvocationHandler{
//真实对象
private object target = null;
/**
*建立代理对象和真实对象的代理关系,并返回对象
*@param target 真实对象
*@return 代理对象
*/
public object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterface(),this);
/**
*代理对象逻辑
*@param proxy 代理对象
*@param method 当前调度方法
*@param args 当前方法参数
*@return 代理结果返回
*@throws Throwable 异常
*/
@override
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之前的服务");
Object object = method.invoke(target,args);
System.out.println("在调度真实对象之后的服务");
return object;
}
}
第一步建立对象和代理对象之间的联系,也就是使用了bind方法用如下语句
Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterface(),this);
生成代理对象,通过目标类的类加载器,和目标类的挂在接口。用当前对象this作为代理逻辑方法的现实方法,它必须实现InvocationHandler接口的invoke方法。
第二步实现代理逻辑方法。invoke方法可以实现代理逻辑。
这样我们进行HelloWorld proxy= (HelloWorld)jdk . bind(new HelloWorldImpl());
生成的就是proxy代理对象,调用方法proxy . sayHelloWorld();
就会输出:
进入代理逻辑方法
在调度真实对象之前的服务
Hello World
在调度真实对象之后的服务
这样通过代理,我们做到了什么事情呢?
你可以看到,我们并没有修改HelloWorldImpl类的sayHello()方法,但是执行出来的代理方法增添了新的内容!如果把目标对象比喻成棒棒糖,那么,代理操