为什么要使用AOP?
-
先来看看一个需求:
-
-
代码的实现:
-
-
可以看到很多重复性的日志
-
官方的说法:
-
代码混乱:越来越多的非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀. 每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.
-
代码分散: 以日志需求为例, 只是为了满足这个单一需求, 就不得不在多个模块(方法)里多次重复相同的日志代码. 如果日志需求发生变化, 必须修改所有模块.
-
-
假设使用以前使用的方案: 动态代理解决上述问题(了解)
-
代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上.
-
-
代码:主要是看代理类代码,了解即可
-
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class ArithmeticCalculatorLoggingProxy {
// 要代理的对象
private ArithmeticCalculator target;
public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {
this.target = target;
}
public ArithmeticCalculator getLoggingProxy(){
ArithmeticCalculator proxy = null;
// 代理对象由哪一个类加载器负责加载
ClassLoader loder = target.getClass().getClassLoader();
// 代理对象的类型,即其中有哪些方法
Class[] interfaces = new Class[]{ArithmeticCalculator.class};
// 当调用代理对象其中的方法时,需执行的代码
InvocationHandler h = new InvocationHandler() {
/**
*
* @param proxy 表示返回刚刚那个代理对象,一般情况下,在 invoke 方法中都不使用该对象(了解)
* 为什么不用,可以输出一下proxy,就发现出异常,栈被挤满,
* 是因为无限循环了,因为会调用toString()方法,当调用该方法又回去调用当前的invoke方法
* 如此就成了死循环,所以就不会直接调用proxy的方法
* @param method 正在被调用的方法
* @param args 调用方法时,传入的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(proxy);
String methodName = method.getName();
// 日志
System.out.println("The moethod " + methodName + " begin with " + Arrays.asList(args));
// 执行方法
Object result = method.invoke(target, args);
// 日志
System.out.println("The moethod " + methodName + " end with " + result);
return result;
}
};
proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loder, interfaces, h);
return proxy;
}
}
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
return result;
}
@Override
public int mul(int i, int j) {
int result = i * j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
public interface ArithmeticCalculator {
int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j);
}
public class Main {
public static void main(String[] args) {
ArithmeticCalculator target = new ArithmeticCalculatorImpl();
ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy();
int result = proxy.add(1,2);
System.out.println("-->" + result);
result = proxy.sub(1,2);
System.out.println("-->" + result);
}
}
-
开发的时候也可以这样写个代理类,但是太麻烦了,所以就有了Spring的AOP
AOP 简介
-
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.
-
AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.
-
在应用 AOP 编程时, 仍然