1.什么是AOP
AOP是面向切面编程(Aspect oriented programing) 。
2.AOP术语
- 连接点
程序执行的某个特定位置:类初始化前后、方法调用前后、异常抛出后
- 切点
定位特定连接点,通过数据库查询的概念来理解切点和连接点的关系很合适:连接点相当于数据库中的记录,而切点相当于查询条件。
- 增强
增强是织入到目标类连接点上的一段程序代码。
- 目标对象
增强逻辑的织入目标类。
- 引介
引介是一种特殊的增强,它为类添加一些属性和方法。
- 织入
织入是将增强添加到目标类具体连接点上的过程。
AOP三种织入方式:编译器织入、类加载器织入、动态代理织入。
- 代理
一个类被织入增强之后,就产生了一个结果类,结果类就是代理类。
- 切面
切面有切点和增强组成。
3.JDK动态代理
public class PerformanceHandler implements InvocationHandler{
private Object target;
public PerformanceHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//此处可写横切逻辑代码,比如日志、性能检测
Object obj = method.invoke(target, args);
//此处可写横切逻辑代码,比如日志、性能检测
return obj;
}
public static void main(String[] args) {
//希望被代理的目标业务类
ForumService target = new ForumServiceImpl();
//将目标业务类和横切代码编织到一起
PerformanceHandler handler = new PerformanceHandler(target);
//创建代理实例
ForumService proxy = (ForumService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
}
}
4.CGLib动态代理
使用JDK创建代理有一个限制,它只能为接口创建代理实例,使用CGLib能够为一个类创建子类,采用非常底层的字节码技术,并在子类中使用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。
public class CglibProxy implements MethodInterceptor{
Enhancer enhancer = new Enhancer();
public Object getProxy(Class class1){
//设置需要创建子类的类
enhancer.setSuperclass(class1);
enhancer.setCallback(this);
//通过字节码技术动态创建子类实例
return enhancer.create();
}
//拦截父类所有方法的调用
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
//此处可写横切逻辑代码,比如日志、性能检测
Object result = proxy.invokeSuper(obj,args);
//此处可写横切逻辑代码,比如日志、性能检测
return result;
}
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
//通过动态生成子类的方式创建代理类
ForumServiceImpl forumServiceImpl = (ForumServiceImpl) proxy.getProxy(ForumServiceImpl.class);
}
}