代理模式
静态代理
代理对象和目标对象实现一样的接口
优点:可以在不修改目标对象的前提下扩展目标对象的功能。
缺点:冗余,由于代理对象要实现于目标对象一致的接口,会产生过多的代理类;不易维护,一旦接口方法增加,目标对象和代理对象都要进行修改。
// 接口类
public interface UserDao {
void save();
}
// 目标对象
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("保存");
}
}
// 静态代理对象
public UserDaoProxy implements UserDao {
private UserDao target;
public UserDaoProxy(UserDao target) {
this.target = target;
}
@Override
public void save() {
// 扩展额外功能
System.out.println("开启事务");
target.sace();
System.out.println("提交事务");
}
}
动态代理
JDK动态代理
动态的在内存中构建代理对象,从而实现目标对象的代理功能。
静态代理在编译时已经实现,编译后的代理类是一个实际的class文件。
动态代理是在运行时动态生成的,编译后没有实际的class文件,而是在运行时生成字节码,并加载到JVM中。
JDK动态代理使用Java的反射相关的类进行实现。
// 动态代理对象
public class UserProxy {
private Object target;
public UserProxy(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 {
System.out.println("开启事务");
// 执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务");
return null;
}
});
}
}