动态代理核心类和接口:
- Proxy类 ---- Proxy.newProxyInstance()用于动态生成代理类实例;
- InvocationHandler接口 ---- 其中的invoke方法用于处理 在代理实例上调用的、被分派过来的 方法。
动态代理步骤:
- 1.创建被代理的类以及接口
- 2.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
- 3.通过Proxy的静态方法 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)创建一个代理实例
- 4.通过代理实例调用方法
被代理的接口:
package dynamicProxy;
public interface TargetInterface {
public void add();
public void delete();
public void update();
public void query();
}
实现了被代理接口的被代理类:
package dynamicProxy;
public class TargetObject implements TargetInterface{
@Override
public void add() {
System.out.println("add方法!");
}
@Override
public void delete() {
System.out.println("delete方法!");
}
@Override
public void update() {
System.out.println("update方法!");
}
@Override
public void query() {
System.out.println("query方法!");
}
}
代理实例的调用处理程序:
package dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理实例的调用处理程序
*/
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public ProxyInvocationHandler(Object target) {
this.target = target;
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeService(method.getName());
//动态代理的本质,使用反射机制实现
Object result = method.invoke(target, args);
afterService(method.getName());
return result;
}
public void beforeService(String msg){
System.out.println(msg+"方法先行业务!");
}
public void afterService(String msg){
System.out.println(msg+"方法结尾业务!");
}
}
测试:
package dynamicProxy;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
TargetObject realObject = new TargetObject();
//通过调用程序处理角色来处理我们要调用的接口对象
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(realObject);
//生成代理实例
TargetInterface proxyInstance = (TargetInterface) Proxy.newProxyInstance(realObject.getClass().getClassLoader(),
realObject.getClass().getInterfaces(),
proxyInvocationHandler
);
/**
* 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。
* 即,当这里用代理实例调用add方法时,方法调用将会被分派到调用处理程序ProxyInvocationHandler的invoke方法。
*/
proxyInstance.add();
System.out.println();
proxyInstance.delete();
System.out.println();
proxyInstance.update();
System.out.println();
proxyInstance.query();
}
}
动态代理优点:
- 1、使真实角色的操作更加纯粹,不用去关注一些公共业务
- 2、公共业务就交给代理角色,实现了业务分工
- 3、公共业务发生拓展时,方便进行集中管理
- 4、一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 5、一个动态代理类可以代理多个类,只要这些类是实现了同一个接口即可