代理模式分为静态代理和动态代理。静态代理就是我们自己定义的代理类,动态代理是程序在运行时生成的代理类。
下面演示下静态代理类。首先我们要定义一个接口:
package com.szy.spring; public interface UserManager { public void addUser(String username,String password); public void deleteUser(int userId); public void modifyUser(int userId,String username,String password); public void findUser(int userId); }
比较常见的对用户进行增删改查。
下面我们常见一个实现类,实现这个接口。
package com.szy.spring; public class UserManagerImpl implements UserManager { public void addUser(String username, String password) { System.out.println("--------UserManagerImpl.addUser()----------"); } public void deleteUser(int userId) { System.out.println("--------UserManagerImpl.deleteUser()----------"); } public void findUser(int userId) { System.out.println("--------UserManagerImpl.findUser()----------"); } public void modifyUser(int userId, String username, String password) { System.out.println("--------UserManagerImpl.modifyUser()----------"); } }
每个方法仅仅是输出一句话。
下面我们定义一个客户端类来调用这些方法。
package com.szy.spring; public class Client { public static void main(String[] args) { UserManager userManager=new UserManagerImpl(); userManager.addUser("coolszy", "kuka"); } }
运行正常输出我们期望的结果。
下面我们需要加入安全性检查,就是调用方法前我们需要进行验证,比较常见的就是权限验证,验证用户是否拥有权限,
比较常见的做法就是在UserManagerImpl类中定义一个检查安全性的方法:
public void checkSecurity() { System.out.println("--------UserManagerImpl.checkSecurity()----------"); }
然后在每个方法中都要调用这个方法。但是这样不符合开-闭原则(Open-Closed principle,简称OCP)。因此我们可以使用代理类来实现这个功能。代理模式很显著的特征就是和目标对象的接口一致。在代理类中我们可以控制目标对象。要控制目标对象我们必须有一个目标对象的引用。为了灵活我们可以把目标对象传到方法中,而不是在方法中实例化。同时我们把安全性检查的代码也放到代理类中,在调用每个方法之前调用这个检查方法,通过代理对我们以前的类没有破坏。
package com.szy.spring; public class UserManagerImplProxy implements UserManager { private UserManager userManager; public UserManagerImplProxy(UserManager userManager) { this.userManager = userManager; } public void addUser(String username, String password) { checkSecurity(); this.userManager.addUser(username, password); } public void deleteUser(int userId) { checkSecurity(); this.userManager.deleteUser(userId); } public String findUser(int userId) { checkSecurity(); return this.userManager.findUser(userId); } public void modifyUser(int userId, String username, String password) { checkSecurity(); this.userManager.modifyUser(userId, username, password); } public void checkSecurity() { System.out.println("--------UserManagerImpl.checkSecurity()----------"); } }
下面修改客户端类。
UserManager userManager=new UserManagerImplProxy(new UserManagerImpl()); userManager.addUser("coolszy", "kuka");
这样总的来说比较灵活。这个依赖关系是我们自己做的,我们完全可以交给spring处理。
按照上面的这种做法有一个缺点,如果接口中方法很多,那么我们实现每一个方法都要添加检查方法checkSecurity(),影响了我们的业务处理。采用静态代理模式我们是没法解决的,这时我们需要使用AOP思想。