为什么要使用AOP呢?我们可以通过下面的一个小需求来找到答案。
需求1-日志:在程序执行期间追踪正在发生的活动
需求2-验证:希望计算器只能处理正数的运算
代码实现一
package xyz.huning.spring4.aop.calculator;
public interface ICalculator {
double add(double x,double y);
double sub(double x,double y);
double mul(double x,double y);
double div(double x,double y);
}
package xyz.huning.spring4.aop.calculator.originimpl;
import java.util.Arrays;
import xyz.huning.spring4.aop.calculator.ICalculator;
public class OriginCalculator implements ICalculator {
@Override
public double add(double x, double y) {
validate(x,y);
System.out.println("before: " + "[x=" + x + ", y=" + y + "]");
System.out.println("execute method add ...");
double result = x + y;
System.out.println("after: " + "[x=" + x + ", y=" + y + "]");
return result;
}
@Override
public double sub(double x, double y) {
validate(x,y);
System.out.println("before: " + "[x=" + x + ", y=" + y + "]");
System.out.println("execute method sub ...");
double result = x - y;
System.out.println("after: " + "[x=" + x + ", y=" + y + "]");
return result;
}
@Override
public double mul(double x, double y) {
validate(x,y);
System.out.println("before: " + "[x=" + x + ", y=" + y + "]");
System.out.println("execute method mul ...");
double result = x * y;
System.out.println("after: " + "[x=" + x + ", y=" + y + "]");
return result;
}
@Override
public double div(double x, double y) {
validate(x,y);
System.out.println("before: " + "[x=" + x + ", y=" + y + "]");
System.out.println("execute method div ...");
double result = x / y;
System.out.println("after: " + "[x=" + x + ", y=" + y + "]");
return result;
}
private void validate(double x, double y)
{
System.out.println("validate parameter: " + Arrays.toString(new double[]{x,y}));
}
}
package xyz.huning.spring4.aop.calculator.originimpl;
public class Main {
public static void main(String[] args) {
OriginCalculator oc1 = new OriginCalculator();
oc1.add(10, 20);
oc1.sub(30, 10);
oc1.mul(10, 10);
oc1.div(20, 10);
}
}
问题
代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀。每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。
代码分散:以日志需求为例,只是为了满足这个单一需求,就不得不在多个模块(方法)里多次重复相同的日志代码。如果日志需求发生变化,必须修改所有模块。