一个例子
查看员工工资
- 启动日志系统
- 启动安全验证系统。
- 验证权限:
如果验证成功,可以查看日志;否则,不能查看日志。
共用的类
日志系统Logger.java
public class Logger {
public void startLogger(){
System.out.println("启动日志系统...");
}
}
安全Security.java
public class Security {
public void startSecurity(){
System.out.println("启动安全系统");
}
}
权限校验Privilege.java
public class Privilege {
private String access; //权限类型
public String getAccess() {
return access;
}
public void setAccess(String access) {
this.access = access;
}
}
普通方式来实现
将方法的实现写在目标类中,类之间的依赖请较强,扩展性不好。
查看工资类
public class SalaryManage {
private Logger logger;
private Privilege privilege;
private Security security;
public SalaryManage(Logger logger,Privilege privilege,Security security){
this.logger = logger;
this.security = security;
this.privilege = privilege;
}
public void showSalary(){
//启动日志系统
logger.startLogger();
security.startSecurity();
if("admin".equals(privilege.getAccess())){
System.out.println("正在查看工资");
}else{
System.out.println("您不具备权限...");
}
}
}
测试类SalaryTest.java
public class SalaryTest {
@Test
public void test(){
Logger logger= new Logger();
Security security = new Security();
Privilege privilege = new Privilege();
privilege.setAccess("admin");
SalaryManage sm = new SalaryManage(logger, privilege, security);
sm.showSalary();
}
}
普通代理模式来实现
该代理模式将目标类的实现交给代理类来实现,减少其他类与目标类之间的依赖关系。
但是代理类中的目标方法写死,一旦目标类改变,代理类还得修改方法。
目标接口类ISalaryManage.java
public interface ISalaryManage {
void showSalary();
}
目标类SalaryManageImpl.java
public class SalaryManageImpl implements ISalaryManage{
@Override
public void showSalary(){
System.out.println("正在查看工资...");
}
}
目标代理类SalaryProxy
public class SalaryProxy implements ISalaryManage{
private Logger logger;
private Privilege privilege;
private Security security;
private ISalaryManage iSalaryManage;
/**
* @param logger
* @param privilege
* @param security
* @param iSalaryManage
*/
public SalaryProxy(Logger logger, Privilege privilege, Security security,
ISalaryManage iSalaryManage) {
super();
this.logger = logger;
this.privilege = privilege;
this.security = security;
this.iSalaryManage = iSalaryManage;
}
@Override
public void showSalary() {
this.logger.startLogger();// 启动日志
this.security.startSecurity();// 安全性框架
if ("admin".equals(this.privilege.getAccess())) {
this.iSalaryManage.showSalary();
} else {
System.out.println("您没有权限");
}
}
}
JDK动态代理来实现
测试类
1. 拦截器的作用究竟是什么?
给目标类和其他类进行赋值
拦截器中的invoke方法,就是代理对象的方法的内容。
2. 代理对象的方法体是什么?
拦截器中invoke方法中的内容
3. 拦截器中的invoke方法的第二个参数method,什么时候进行赋值
代理对象调用方法的时候,就进入了拦截器中invoke方法
4. 动态代理模式到底解决了什么问题。
过滤器SalaryInterceptor
/**
* 1、把日志系统、安全系统、权限导入进来
* 2、把目标类导入进来
* 3、上述两类通过构造函数赋值
* @author lzl
* @since 5.0
*/
public class SalaryInterceptor implements InvocationHandler{
private Logger logger;
private Privilege privilege;
private Security security;
private ISalaryManage iSalaryManage;
/**
* @param logger
* @param privilege
* @param security
* @param iSalaryManage
*/
public SalaryInterceptor(Logger logger, Privilege privilege, Security security,
ISalaryManage iSalaryManage) {
super();
this.logger = logger;
this.privilege = privilege;
this.security = security;
this.iSalaryManage = iSalaryManage;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.logger.startLogger();// 启动日志
this.security.startSecurity();// 安全性框架
if("admin".equals(this.privilege.getAccess())){
//调用目标类的目标方法
method.invoke(this.iSalaryManage, args);
}else{
System.out.println("您没有权限");
}
return null;
}
}
测试方法SalaryTest
public class SalaryTest {
@Test
public void textForJdkProxy(){
Logger logger= new Logger();
Security security = new Security();
Privilege privilege = new Privilege();
privilege.setAccess("aa");
ISalaryManage ism = new SalaryManageImpl(); //目标类
SalaryInterceptor interceptor = new SalaryInterceptor(logger, privilege, security,ism);
/**
* 1、目标类的类加载器
* 2、目标类的所有的接口
* 3、拦截器
*/
ISalaryManage proxy = (ISalaryManage) Proxy.newProxyInstance(ism.getClass()
.getClassLoader(), ism.getClass().getInterfaces(), interceptor);
proxy.showSalary();//代理对象的代理方法
}
}