静态代理
首先看看一般的代理模式即静态代理。我们直接来看代码。
public interface HelloService{
void sayHello();
}
/**
* 被代理类
*/
public class HelloServiceImpl implements HelloService{
public void sayHello(){
System.out.println("Hello World!");
}
}
/**
* 代理类
*/
public class HelloServiceProxy implements HelloService{
private HelloServiceImpl target;
public HelloServiceProxy(HelloServiceImpl target){
this.target = target;
}
public void sayHello(){
System.out.println("额外操作")
target.sayHello();
}
}
public class Client{
public static void main(String[] args){
HelloService service = new HelloServiceProxy(new HelloServiceImpl());
service.sayHello()
}
}
被代理类与代理类实现相同的接口,代理类的方法实现就是调用被代理类的同名方法,同时加入一些额外操作,比如通用的日志打印等。这就是代理。
但这种方式的弊端很明显,代理类与被代理耦合太严重。
- 方法名变了,代理类的方法名也要修改;
- 新增了方法,代理类也要新增方法;
- 被代理类实现了新接口,代理类也要实现新接口。
即,代理类需要我们手动地编写修改,这很麻烦。动态代理就在这种情况下应运而生。
JDK动态代理
上面的例子中代理类与别代理类实现了相同的接口,JDK动态代理的适用情景和上面一样,被代理类必须实现接口。
JDK动态代理通过增加一个中间层InvocationHandler来解耦。
public class MyJdkProxy implements InvocationHandler{
private Object target;
public Object getProxyInstance(Object target){
this.target = target;
return Proxy.newInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);