代理模式:简单来说即在不改变目标类代码的情况下,对目标类进行功能扩展。
一:静态代理
直接以代码来讲解:
1.创建一个接口
public interface TargetClass {
public void sayHi();
}
2.接下来对这个接口进行实现:
public class TargetClassImp implements TargetClass {
@Override
public void sayHi() {
System.out.println("sayHi()........");
}
}
3.下面对实现类进行静态代理:
public class ProxyClass implements TargetClass {
private TargetClass targetClass;
public ProxyClass(TargetClass targetClass) {
this.targetClass = targetClass;
}
@Override
public void sayHi() {
System.out.println("方法执行前.......");
targetClass.sayHi();
System.out.println("方法执行后.......");
}
}
4.使用代理:
public static void main(String[] args) {
ProxyClass proxyClass = new ProxyClass(new TargetClassImp());
proxyClass.sayHi();
}
通过上述过程,我们可以分析下静态代理的缺点:由于代理对象需要实现和目标对象一样的接口,如果接口类繁多,也会导致代理类繁多;同时一旦接口增加方法,则目标对象和代理类都需要维护。
二.动态代理
正是由于静态代理存在上述的缺点,目前主要使用的是动态代理。介绍动态代理时,同样通过代码来讲解。
1.创建接口:
public interface TargetClass {
public void sayHi();
}
2.实现类实现接口:
public class TargetClassImp implements TargetClass {
@Override
public void sayHi() {
System.out.println("sayHi()........");
}
}
3.动态代理:
public class ProxyClass implements InvocationHandler {
private TargetClass targetClass;
public ProxyClass(TargetClass targetClass) {
this.targetClass = targetClass;
}
/**
*
* @param proxy 最后生成的代理类
* @param method 要调用的目标方法,sayHi()方法
* @param args 目标方法的参数,sayHi()方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理方法执行前......");
Object result = method.invoke(targetClass,args); //targetClass,实现类,需要通过实现类去调用方法
System.out.println("代理方法执行后.....");
return result;
}
}
4.使用动态代理进行增强:
/**
* TargetClass.class.getClassLoader():TargetClass的类加载器
* new ProxyClass(new TargetClassImp()):代理类
* @param args
*/
public static void main(String[] args) {
TargetClass targetClass = (TargetClass) Proxy.newProxyInstance(TargetClass.class.getClassLoader(),new Class<?>[]{TargetClass.class},
new ProxyClass(new TargetClassImp()));
targetClass.sayHi();
}
动态代理的优点:就算接口新增其他方法,也不需要对代理类进行额外的修改。