java动态代理技术解疑
为何选择动态代理?相对于静态代理有什么优势?
优势主要体现在采用反射技术实现,这样我们就不用为每一个被代理对象编写一个代理类,并且被代理的业务逻辑也可以放在一块集中处理。
代码主要的区别:
静态代理中的代理类必须要自己实现。并且持有相应的被代理的的类型。
interface Person {
public void say();
}
class Teacher implements Person {
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println(" my name is eric");
}
}
class PersonProxy implements Person {
private Person person;
public PersonProxy(Person person) {
this.person = person;
}
@Override
public void say() {
// TODO Auto-generated method stub
beforeSay();
person.say();
afterSay();
}
private void beforeSay() {
System.out.println("before");
}
private void afterSay() {
System.out.println("after");
}
}
动态代理中的主要起作用的handler,而handler中的类型却可以设置为object,因为我们采用的反射机制具体类型可以在运行中得知。所以handler能够处理一切继承自object的类。
class Handler implements InvocationHandler {
public Handler(Object person) {
this.obj = person;
}
private Object obj;
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeSay();
Object ob = method.invoke(obj, args);
afterSay();
return ob;
}
private void beforeSay() {
System.out.println("hi,all");
}
private void afterSay() {
System.out.println("thanks");
}
}
Teacher t1 = new Teacher(); Handler handler = new Handler(t1); Person t2 = (Person) Proxy.newProxyInstance( ProxyTest.class.getClassLoader(), t1.getClass().getInterfaces(), handler); t2.say(); Dog d1 = new Dog(); Handler handler2 = new Handler(d1); Animal d2 = (Animal) Proxy.newProxyInstance( ProxyTest.class.getClassLoader(), d1.getClass().getInterfaces(), handler2); d2.hawl();
在上述情况下,我们解耦了被代理对象的类型,但是却发现每次还需要创建handler,创建proxy对象,如果想要解决这个问题我们可以采用工厂模式来解决这个问题。
class ProxyFactory {
public static Object getProxy(final Object obj) {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
doBefore();
Object ob = method.invoke(obj, args);
doAfter();
return ob;
}
private void doBefore() {
System.out.println("before");
}
private void doAfter() {
System.out.println("after");
}
};
return Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(), obj
.getClass().getInterfaces(), handler);
}
}
这样之后,我们在需要代理对象的场合时就非常方便了。不需要显示的创建handler,不需要显示的创建proxy对象。只需要传递被代理的对象,所有其他的问题交由反射来解决。
Dog d1 = new Dog(); Animal d2 = (Animal) ProxyFactory.getProxy(d1); d2.hawl();
浙公网安备 33010602011771号