关于java代理,我觉得一种比较形象的解释就是明星和经纪人。明星的主要任务是唱歌和演戏,如果所有的事都由明星来做那么明星就会累死,所以需要一个经纪人来帮他分担其他的任务。这也正是java所倡导的单一职责原则:一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。
java普通的代理:
package com.design.proxy;
public interface Proxyable {
void handle();
}
package com.design.proxy;
public class Real implements Proxyable{
@Override
public void handle() {
System.out.println("I am the real entity!");
}
}
package com.design.proxy;
public class Proxy implements Proxyable{
private Real real;//被代理的类
@Override
public void handle() {
System.out.println("代理之前");
if(real ==null){
real = new Real();
}
real.handle();
System.out.println("代理之后");
}
public static void main(String args[]){
Proxy p = new Proxy();
p.handle();
}
}
可以看出静态代理一个代理类只能代理一个系列(实现同一个接口的一些列类),如果一个项目有多个系列需要代理,那么就会需要很多的代理类,在这种情况下,java推出了更灵活的动态代理。
java动态代理涉及到java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
InvocationHandler接口只有一个Object invoke(Object proxy,Method method,Object[] args)throws Throwable方法
Proxy类中的主要方法
public static ObjectnewProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throwsIllegalArgumentException
该方法通过类加载器、被代理类的接口以及InvocationHandler类来动态生成一个代理对象,在调用代理所代理的方法时,会调用InvocationHandler的invoke方法,所以实际要处理的内容在invoke方法中实现即可。
动态代理示例:
package com.thinkingInJava.reflex.dynamicProxy;
public interface Carable {
public void horn();
}
package com.thinkingInJava.reflex.dynamicProxy;
public interface Personable {
public void say();
}
package com.thinkingInJava.reflex.dynamicProxy;
public class CarImpl implements Carable {
@Override
public void horn() {
System.out.println("bibibibi~~");
}
}
package com.thinkingInJava.reflex.dynamicProxy;
public class PersonImpl implements Personable{
@Override
public void say() {
System.out.println("hi, how are you?");
}
}
package com.thinkingInJava.reflex.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynicalProxy implements InvocationHandler{
private Object obj;
/**
* 根据给定的对象获取其加载器和接口,生成一个代理对象
* @param obj
* @return
*/
public Object bind(Object obj){
this.obj = obj;//实际要访问的对象,即被代理的对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("代理之前");
Object value=method.invoke(this.obj, args);//调用method的invoke方法
System.out.println("代理之后");
return value;
}
}
package com.thinkingInJava.reflex.dynamicProxy;
public class MainTest {
public static void main(String args[]){
DynicalProxy proxy = new DynicalProxy();
Carable car = (Carable) proxy.bind(new CarImpl());//调用bind方法生成一个动态代理对象
car.horn();//调用代理的horn方法,实际上会调用DynicalProxy的invoke方法
System.out.println("=========person======");
Personable person = (Personable) proxy.bind(new PersonImpl());
person.say();
}
动态代理比较适合对一些类在方法执行前后做一些比较统一的操作,如日志管理等。