springaop使用背景
1. 代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀,每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点;
2. 代码分散:以日志需求伪列,只是为了满是这个单一需求,就不得不在多个方法里多次重复相同的日志代码,如果日志需求发生变化,就必须修改所有模块;
3. 动态代理
4. 在应用AOP编程的时候,仍然需要定义公共功能,但可以明确的定义这个功能在哪里,以书面方式应用,并且不必修改受影响的类,这样一来横切关注点就被模块化到特殊的对象(切面)里;
1. AOP的好处:每个事务逻辑位于一个位置,代码不分散,便于维护升级
2. 业务模块更简洁,只包含核心业务代码
通知:切面里面实现的方法就叫做通知
目标:被通知的对象,指这里的业务逻辑方法
代理:指的是向目标对象应用通知之后返回的对象
连接点:程序执行的某个特定位置,如:某个方法执行之前,某个方法执行之后,或者某个方法抛出异常时
切点:每个类中有多个连接点,通过切点定位特定的连接点,它俩不是一一对应的关系;连接点相当于库里数据的话,切点就等于查询条件
代理的方式处理日志
业务逻辑方法
package com.tiger.aop;
public class MathematicsCalculatorImpl implements MathematicsCalculator {
@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;
}
}
代理方法
package com.tiger.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class MathematicsCalculatorLoggingProxy {
//创建一个要代理的对象
private MathematicsCalculator target;
public MathematicsCalculatorLoggingProxy(MathematicsCalculator target) {
super();
this.target = target;
}
//
public MathematicsCalculator getLoggingProxy(){
MathematicsCalculator proxy =null;
//代理对象由哪一个类加载器负责
ClassLoader loader = target.getClass().getClassLoader();
//代理对象的类型,即其中有哪些方法
Class[] interfaces = new Class[]{MathematicsCalculator.class};
//当调用代理对象中的代码时,要执行的代码
InvocationHandler h = new InvocationHandler() {
/**
* Proxy:正在返回的那个代理对象,一般情况下,在invoke中都不使用该对象
* method:正在被调用的方法
* args:调用方法时传入的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodName = method.getName();
System.out.println("The "+methodName+" method is begin.."+Arrays.asList(args));
Object result = method.invoke(target, args);
System.out.println("The "+methodName+" method is end......."+result);
return result;
}
};
proxy = (MathematicsCalculator) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
调用main
package com.tiger.aop;
public class MainCalculate {
public static void main(String[] args) {
MathematicsCalculator target = new MathematicsCalculatorImpl();
MathematicsCalculator proxy = new MathematicsCalculatorLoggingProxy(target).getLoggingProxy();
int result =proxy.add(2, 3);
System.out.println(result);
result = proxy.div(10, 2);
System.out.println(result);
}
}