1. 问题
在面向对象编程思想中,我们可以根据类的继承关系纵向对方法进行继承和管理。但是,我们可能需要同时对某些方法进行非核心功能的添加,例如对某些方法添加日志、事务等功能。在这些场景下,面向对象编程思想就无法解决,我们需要代理技术来解决这一问题。
2. 代理技术
2. 1 介绍
代理模式是二十三种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦。调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰,同时让附加功能能够集中在一起也有利于统一维护。
生活中的代理:
- 广告商找大明星拍广告需要经过经纪人
- 合作伙伴找大老板谈合作要约见面时间需要经过秘书
- 房产中介是买卖双方的代理
- 太监是大臣和皇上之间的代理
代理在开发中实现的方式具体有两种:静态代理和动态代理技术
2.2 静态代理
静态代理就是手动创建一个类,并实现我们需要的方法接口。例如,原先有一个计算器接口,有加减乘除四个方法。若我们需要为这四个方法添加日志,那就创建一个类实现该接口,并在加减乘除四个方法中分别添加日志功能。
如代码所示:
public class CalculatorStaticProxy implements Calculator {
// 将被代理的目标对象声明为成员变量
private Calculator target;
public CalculatorStaticProxy(Calculator target) {
this.target = target;
}
@Override
public int add(int i, int j) {
// 附加功能由代理类中的代理方法来实现
System.out.println("参数是:" + i + "," + j);
// 通过目标对象来实现核心业务逻辑
int addResult = target.add(i, j);
System.out.println("方法内部 result = " + result);
return addResult;
}
……
}
静态代理确实实现了解耦,但是由于代码都写死了,完全不具备任何的灵活性。就拿日志功能来说,将来其他地方也需要附加日志,那还得再声明更多个静态代理类,那就产生了大量重复的代码,日志功能还是分散的,没有统一管理。
提出进一步的需求:将日志功能集中到一个代理类中,将来有任何日志需求,都通过这一个代理类来实现。这就需要使用动态代理技术了。
2.3 动态代理介绍
动态代理技术主要有以下两种:
- JDK动态代理:JDK原生的实现方式,需要被代理的目标类必须实现接口!他会根据目标类的接口动态生成一个代理对象!代理对象和目标对象有相同的接口!(拜把子)
- cglib:通过继承被代理的目标类实现代理,所以不需要目标类实现接口!(认干爹)
3. 总结
代理方式可以解决附加功能代码干扰核心代码和不方便统一维护的问题。
他主要是将附加功能代码提取到代理中执行,不干扰目标核心代码!
但是我们也发现,无论使用静态代理和动态代理(jdk,cglib),程序员的工作都比较繁琐,需要自己编写代理工厂等。
我们在实际开发中,不需要编写代理代码,我们可以使用Spring AOP框架,他会简化动态代理的实现。