概念
什么叫代理
举个例子比如你想买房子,但是买房子的流程很复杂你不是很清楚,所以你就去找房产中介帮你处理好所有的事情,然后你自己就只负责付钱收房就好了就好了。
代理模式就是这样,你只需要关心你所需要关心的核心问题,比如核心业务处理,一些其他杂碎的事情如日志记录等,利用代理的方式去实现。
静态代理和动态代理
静态代理
这种代理模式要求代理对象和被代理对象实现同一个接口
public interface Ihello{
public void sayHello();
}
被代理类
public class Hello implement Ihello{
@Override
public void sayHello(){
System.out.println("你好");
}
}
代理类
public class StaticProxyHello implement Ihello{
private Hello hello;
public StaticProxyHello(Hello hello){
this.hello = hello;
}
@Override
public void sayHello(){
System.out.println("before");
hello.sayHello();
System.out.println("after");
}
}
接口测试
public class Main {
public static void main(String[] args) {
StaticProxyHello proxy = new StaticProxyHello(new Hello());
proxy.sayHello();
}
}
输出结果
before
你好
after
这样就可以在不修改原类的情况下对类的功能进行增强
动态代理
被代理的类也必须要实现接口
public interface HelloInter {
public void method();
}
被代理类
public class Hello implements HelloInter {
public void method(){
System.out.println("Hello");
}
}
代理类,需要实现InvocationHandler
public class HelloProxy implements InvocationHandler {
private Object obj;
public void bind(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before: " + method.getName());
method.invoke(obj, args);
System.out.println("after: " + method.getName());
return null;
}
}
测试类
public class ProxyTest {
@Test
public void testProxy(){
HelloProxy proxy = new HelloProxy();
proxy.bind(new Hello());
HelloInter hello = (HelloInter) Proxy.newProxyInstance(HelloInter.class.getClassLoader(), new Class[] {HelloInter.class}, proxy);
hello.method();
}
}
测试结果
before: method
Hello
after: method
总结
- 代理模式可以在不改变目标类的情况下对功能进行扩展
- 静态代理编译时便生成class文件,动态代理运行时通过反射生成对应的class文件
- 静态代理类中需要制定被代理类,以及实现和被代理类相同的接口,一个代理类能服务的目标类有限
- 动态代理可以制定object类型,且只需要实现InvocationHandler,一个代理处理器可以服务多个目标类
- 对于某个功能进行增强可以考虑静态代理,对一系列功能进行相同的增强,可以考虑动态代理(如日志处理,异常捕获等)