1.静态代理:
需求:要在实现类中添加功能,可是很多时候我们不能更改源码,这时候使用代理完成。
如:需要增添日志信息。
- 接口:
public interface Service {
public void add();
public void delete();
public void upadate();
public void query();
}
- 实现类:
public class ServiceImpl implements Service {
public void add() {
System.out.println("add");
}
public void delete() {
System.out.println("delete");
}
public void upadate() {
System.out.println("update");
}
public void query() {
System.out.println("query");
}
}
- 代理:
public class ServiceProxy implements Service{
private ServiceImpl service;
public ServiceProxy() {
}
public ServiceProxy(ServiceImpl service) {
this.service = service;
}
public void add() {
Log("add");
service.add();
}
public void delete() {
Log("delete");
service.delete();
}
public void upadate() {
Log("update");
service.upadate();
}
public void query() {
Log("query");
service.query();
}
public void Log(String name){
System.out.println("[DeBug]:正在执行:"+name);
}
}
- 测试:
@Test
public void test(){
ServiceImpl service = new ServiceImpl();
ServiceProxy serviceProxy = new ServiceProxy(service);
serviceProxy.upadate();
}
1.1 特点:
代理类需要实现接口,本质上是在实现接口方法内调用实现类的方法
2.动态代理
使用了java.lang.reflect包下的InvocationHandler接口和proxy类的newProxyInstance()方法 。
本质上会在内存中动态的构建代理对象,通过代理对象调用目标对象方法。
Object invoke(Object proxy, 方法 method, Object[] args)throws Throwable
处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。
参数
proxy - 调用该方法的代理实例
method -所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
proxy类的静态方法:
public static Object newProxyInstance(ClassLoader loader , 类<?>[] interfaces , InvocationHandler h) throws IllegalArgumentException
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序
loader :类加载器来定义代理类
interfaces : 代理类实现的接口列表
h : 动态代理方法在执行时,会调用h里面的invoke方法去执行
动态代理类
public class dynamicProxy {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
Object o = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log(method.getName());
method.invoke(target, args);
return null;
}
}
);
return o;
}
public void Log(String inf){
System.out.println("[DeBug]:"+inf+"已经执行");
}
}
public class Mytest {
public static void main(String[] args) {
ServiceImpl service = new ServiceImpl();
dynamicProxy dynamicProxy = new dynamicProxy();
dynamicProxy.setTarget(service);
Service proxy = (Service) dynamicProxy.getProxy();
proxy.add();
}
}