spring框架学习之路(一)-入门基础(1)-IOC(控制反转)&DI(依赖注入);
之前写了关于spring的内核IOC&DI的一些内容,现在接着写spring的另一个重要概念AOP。
AOP(Aspect Oriented Programming):面向切面编程。与OOP(面向对象编程)自上而下的程序结构不同的是,AOP是针对于程序切面。
比如日志记录,我们需要对多个类中的多个方法执行前或执行后进行记录日志,如果我们对每一个方都添加相同的记录日志的代码,就违反了DRY(Don’t repeat yourself)原则。所以出现了AOP,AOP就是在程序的水平结构上进行整体程序设计,而不需要针对每一个方法进行设计。
要了解AOP,就必须了解“代理模式”(不了解的百度吧…设计模式的坑以后填…),而AOP利用的就是“动态代理”。
简单来说,AOP主要就是动态生成和不同的“真实角色”相对应的“代理角色”。核心就是InvocationHandler接口 和Proxy.newProxyInstance() 方法。
老规矩,举个栗子~~~
//抽象角色
public interface AbsRole {
void doActive();
}
//真实角色
public class RealRole implements AbsRole {
@Override
public void doActive() {
System.out.println("active from real role!");
}
}
然后创建一个InvocationHandler,InvocationHandler只有一个invoke()方法,而我们只需要在里面实现method.invoke(obj, args);就可以调用 对象obj的方法method,此方法参数为args,返回值为res。
在这条语句前后加入逻辑,就可以实现每次执行方法method时都会附带执行前后逻辑。(这里就是前后的两条输出语句)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyRole implements InvocationHandler {
private Object obj;
public ProxyRole(Object obj) {
super();
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("previous method");
Object res=method.invoke(obj, args);
System.out.println("after method");
return res;
}
}
main方法的执行方法为:
public static void main(String[] args) {
RealRole real=new RealRole();
AbsRole abs=(AbsRole) Proxy.newProxyInstance(RealRole.class.getClassLoader(), RealRole.class.getInterfaces(), new ProxyRole(real));
abs.doActive();
}
大体逻辑执行过程就是:
通过Proxy.newProxyInstance()方法生成一个对象,此对象继承$Proxy0类,并实现真实角色的接口,并且此对象拥有一个InvocationHandler h对象的应用。然后用一个抽象角色abs引用这个对象。
执行abs.doActive()时,此对象在doActive()方法中的具体实现就是调用h.invoke()方法,这样在h.invoke()中就实现了对真实角色方法的执行。
**另外需要注意的是,在ProxyRole类中
public Object invoke(Object proxy, Method method, Object[] args)
方法中的proxy对象不是真实角色的应用,而是动态生成的代理角色(就是那个继承自$Proxy0类的对象)的引用。**