为什么要使用代理?
假如我们是团队开发,那么本团队的某个类可能并不愿意暴露给其他的调用者.这时候又需要用到这个类的一些功能,那么最好的方式就是以代理的方式提供给调用者.对于一个掉用者来说,它仅仅需要的是知道提供给它的类能执行某个业务逻辑就行了.它完全没必要清楚的了解真正的实施者是谁.
另外对于切面性问题也可以使用代理,
例如:在用户管理类,有添加、删除两个个方法,已经定义好了,但是来了新需求,要在每个方法执行之前加一些验证信息,这样,对于每一个方法都要进行修改,这时候就违背了开闭原则。
代码示例如下:
接口:
public interface UserManager {
public void addUser(String userName, String password);
public void delUser(String userId);
}
没有代理的实现类:
public class UserManagerImp implements UserManager {
public void addUser(String userName, String password) {
//添加方法之前加入验证方法
checkSecurity();
System.out.println("--------UserManager.addUser()------");
}
public void delUser(String userId) {
//删除方法之前加入验证方法
checkSecurity();
System.out.println("--------UserManager.delUser()------");
}
//需要加入的验证方法。
public void checkSecurity() {
System.out.println("-----checkSecurity----");
}
}
加入静态代理的实现类:
public class UserManagerImplProxy implements UserManager {
private UserManager userManager;
//构造函数,DI注入方式
public UserManagerImplProxy(UserManager userManager) {
this.userManager = userManager;
}
public void addUser(String username, String password) {
checkSecurity();//加入验证
userManager.addUser(username, password); //执行方法
}
public void delUser(int userId) {
checkSecurity();//加入验证
userManager.delUser(userId);
}
//需要加入的验证方法。
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
}
但是静态代理并没有解决真正的问题,也就是说静态代理类还是违背了开闭原则。于是动态代理就出现了:
接口
public interface UserManager {
public void addUser(String userName, String password);
public void delUser(String userId);
}
实现类:
public class UserManagerImp implements UserManager {
public void addUser(String userName, String password) {
System.out.println("--------UserManager.addUser()------");
}
public void delUser(String userId) {
System.out.println("--------UserManager.delUser()------");
}
}
动态代理实现类
public class SecurityHandler implements InvocationHandler {
private Object targetObject;
//生成代理实例
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
}
//执行方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//执行方法前进行验证
checkSecurity();
//执行目标类的方法
Object rest = method.invoke(targetObject, args);
return rest;
}
//需要加入的验证的方法
public void checkSecurity() {
System.out.println("-----checkSecurity----");
}
}
客户端:
public class Client {
public static void main(String[] args) {
//实例化代理类
SecurityHandler handler = new SecurityHandler();
//通过代理类来实例化userManager
UserManager userManager = (UserManager)handler.createProxyInstance(new UserManagerImp());
//执行添加方法,实际上是在代理类的invoke方法中执行。
userManager.addUser("zhang san ", "123");
}
}