一、概念java
代理模式为其余对象提供一个代理以控制对这个对象的访问,属于结构性模式。从代码的角度来分,代理能够分为两种:一种是静态代理,另外一种是动态代理。 静态代理就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就肯定了。 动态代理类的源码是在程序运行期间根据反射等机制动态的生成,因此不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时肯定。 bash
二、模式结构ide
三、使用场景优化
四、优缺点ui
优势:this
缺点:spa
五、实例代理
静态实例code
public interface IUserDao {
int save();
}
复制代码
public class UserDao implements IUserDao {
@Override
public int save() {
return 0;
}
}
复制代码
public class UserDaoProxy implements IUserDao {
//接收保存目标对象
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target = target;
}
@Override
public int save() {
return target.save();
}
}
复制代码
动态实例:cdn
仍是使用静态代理的IUserDao和UserDao 类,改造UserDaoProxy 类,利用java的newProxyInstance动态生成实例。
public class UserDaoProxy {
//维护一个目标对象
private Object target;
public UserDaoProxy(Object target) {
this.target = target;
}
//给目标对象生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//运用反射执行目标对象方法
Object returnValue = method.invoke(target, args);
return returnValue;
}
}
);
}
}
复制代码
public static void main(String[] args) {
// 目标对象
IUserDao target = new UserDao();
System.out.println(target.getClass());
// 给目标对象,建立代理对象
IUserDao proxy = (IUserDao) new UserDaoProxy(target).getProxyInstance();
proxy.save();
}
复制代码