Java动态代理
什么是代理
代理一词顾名思义就是间接的代替委托者完成一些事,生活中常见的中介、旅行社等等都是一些代理;
而代理模式也是Java中比较重要的一种设计模式,目的也是为其他对象提供一种代理以控制对这个对象的访问。
为了保持行为的一致性,代理类和委托类通常会实现相同的接口。
动态代理的用途
动态代理的用途与装饰模式很相似,就是为了对某个对象进行增强。
动态代理相关接口、类的介绍
Interface InvocationHandler
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。
Object invoke(Object targetObject, Method method, Object[] args)
- targetObject : 需要被代理的对象
- method : 被代理对象的某个方法
- args : 相对于被调用方法来说的实参
- 返回的Object : 这个是调用被代理对象的方法的返回的值
其次是重要的PROXY类,它是JAVA.LANG.REFLECT包下的
Class Proxy
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
创建动态代理我们常用的方法就是如下的静态方法:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
- loader : 代理类的类加载器
- interfaces : 代理类实现的一个或者多个接口
- h : 指派方法调用的调用处理程序
- 返回的Object : 一个增强的代理角色
简单的例子
首先是代理以及委托者都需要实现的接口
//售票处
public interface Tiketing {
public void sellTicket(String plan);
}
其次是委托者
//代理商
public class Agent implements Tiketing {
@Override
public void sellTicket(String plan) {
System.out.println("你要去" + plan + ",需要支付10000元");
}
}
用例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//代理商要向顾客卖票要收取辛苦费
public class Test {
// public void fun1() {
// Tiketing agent = new Agent();
// agent.sellTicket("日本");
// }
public void fun2() {
//谁调用就用谁的类加载器加载
ClassLoader loader = this.getClass().getClassLoader();
//需要增强类的实现的接口
Class[] interfaces = {Tiketing.class};
//
InvocationHandler agentinvocation = new AgentInvocationHandler(new Agent());
//增强的对象
Tiketing agent = (Tiketing) Proxy.newProxyInstance(loader, interfaces, agentinvocation);
agent.sellTicket("日本");
}
public static void main(String[] args) {
//new Test().fun1();
new Test().fun2();
}
}
class AgentInvocationHandler implements InvocationHandler {
private Agent agent;
//传入需要增强的对象
public AgentInvocationHandler(Agent agent) {
this.agent = agent;
}
@Override
public Object invoke(Object obj, Method me, Object[] param) throws Throwable {
System.out.println("请给辛苦费1000元!");
me.invoke(agent, param);
System.out.println("谢谢你,欢迎下次再来");
return null;
}
}
通用的动态代理工厂
需要增强功能的对象之前的增强内容
//前置增强
public interface Advance {
public void beforeMethod();
}
需要增强功能的对象之后的增强内容
//后置增强
public interface After {
public void afterMethod();
}
代理对象与被增强对象需要共同实现接口
public interface Ticketing {
public void sellTicket(String plan);
}
被增强对象实现接口
public class Agent implements Ticketing {
public Agent() {}
@Override
public void sellTicket(String plan) {
System.out.println("你要去" + plan + ",需要支付10000元!");
}
}
代理工厂
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
//前置增强
private Advance advance;
//后置增强
private After after;
//增强对象
private Object targetObject;
public ProxyFactory() {}
public Advance getAdvance() {
return advance;
}
public void setAdvance(Advance advance) {
this.advance = advance;
}
public After getAfter() {
return after;
}
public void setAfter(After after) {
this.after = after;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public Object createProxy() {
//获取类加载器
ClassLoader loader = this.getClass().getClassLoader();
//获取目标对象实现的接口
Class[] interfaces = this.targetObject.getClass().getInterfaces();
//调用的处理器
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object obj, Method me, Object[] params) throws Throwable {
//添加前置增强
if(advance != null) {
advance.beforeMethod();
}
//调用平常的方法
Object result = me.invoke(targetObject, params);
//后置增强
if(after != null) {
after.afterMethod();
}
return result;
}};
return Proxy.newProxyInstance(loader, interfaces, handler);
}
}
对代理工厂的简单的测试
public class Test {
public static void main(String[] args) {
//创建代理工厂
ProxyFactory factory = new ProxyFactory();
//被增强对象
Agent agent = new Agent();
factory.setTargetObject(agent);
//前置增强
factory.setAdvance(new Advance() {
public void beforeMethod() {
System.out.println("你需要购票之前支付辛苦费2500元");
}
});
//后置增强
factory.setAfter(new After() {
public void afterMethod() {
System.out.println("谢谢你的惠顾,下次再来");
}
});
//获得增强的代理对象
Ticketing ticketAgent = (Ticketing) factory.createProxy();
//卖票
ticketAgent.sellTicket("日本");
}
}