一直觉得对AOP了解得比较清楚了,不就是面向切面编程嘛,应用最多的地方,就是日志打印,没什么难点。可是有一天一个朋友微信发了一张图,问了两个问题:
1、Spring AOP的设计原理是什么?
2、在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同?
我发现完全蒙圈,根本答不上来啊,真是汗颜,趁有空,赶紧抽时间整理下。

如果不用AOP,我们平时打印日志是这样的:

public class AOPTest {

	public boolean A(String a) {
		if (a.equals("a")) {
			return true;
		} else {
			return false;
		}
	}

	public boolean B(String b) {
		if (b.equals("a")) {
			return true;
		} else {
			return false;
		}
	}

	public boolean C(String c) {
		if (c.equals("a")) {
			return true;
		} else {
			return false;
		}
	}

	public static void main(String[] args) {
		AOPTest te = new AOPTest();
		if (te.A("a")) {
			System.out.println("我是A方法");
		} else {
			System.out.println("我不是A方法");
		}
		if (te.B("b")) {
			System.out.println("我是B方法");
		} else {
			System.out.println("我不是B方法");
		}
		if (te.C("C")) {
			System.out.println("我是C方法");
		} else {
			System.out.println("我不是C方法");
		}
	}

}

你会发现,打印个日志简直要人命,到处System.out,如果使用AOP,代码就会简洁很多,比如:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;

public class AOPTest {

	@Around("bean(*Service)") // 指定要监控的bean中的方法
	public Object testObject(ProceedingJoinPoint jp) throws Throwable { // 参数的意思是代理执行原软件中的方法
		System.out.println(jp.getSignature() + "开始执行"); // 在方法执行之前执行
		Object val = jp.proceed();
		System.out.println(jp.getSignature() + "执行成功");// 在方法执行之后执行
		return val;
	}

}

storm面试问题_AOP

我们都知道,软件开发分为持久层、业务层和控制层,通过切面编程,现在所有业务层的方法执行前后都会打出日志,所以:

1、什么是Spring AOP?
在面向对象编程中,关键的单元是对象,但AOP的关键单元是切面(关注点),像日志或者事务这些分散的切面(横切关注点——可以影响到整个应用的关注点)应该被尽量地集中到一个地方以方便管理(事务管理、权限、日志、安全)。而AOP就是作用于这些横切关注点,使得代码在当下和将来都变得容易维护,一般AOP通过如下方式进行使用:
使用AspectJ 注解风格
使用Spring XML 配置风格

2、简述一下Spring AOP的设计原理
主要的分代理的创建和代理的调用两部分,比如UML图:

storm面试问题_System_02

1)代理的创建
创建代理工厂:拦截器数组,目标对象接口数组,目标对象。
创建代理工厂时,默认会在拦截器数组尾部再增加一个默认拦截器 —— 用于最终的调用目标方法。
当调用 getProxy 方法的时候,会根据接口数量大余 0 条件返回一个代理对象(JDK or Cglib)。
注意:创建代理对象时,同时会创建一个外层拦截器,这个拦截器就是 Spring 内核的拦截器,用于控制整个 AOP 的流程。
2)代理的调用
当对代理对象进行调用时,就会触发外层拦截器。
外层拦截器根据代理配置信息,创建内层拦截器链。创建的过程中,会根据表达式判断当前拦截是否匹配这个拦截器。而这个拦截器链设计模式就是职责链模式。
当整个链条执行到最后时,就会触发创建代理时那个尾部的默认拦截器,从而调用目标方法,最后返回。

storm面试问题_storm面试问题_03

3、AOP有哪些可用的实现?
基于Java的主要AOP实现有:
AspectJ
Spring AOP
JBoss AOP

4、Spring中有哪些通知类型(advice)?

Before(前置通知): 连接点之前执行,除非抛异常,否则没有能力中断执行流(@Before 注解)
After(后置通知): 无论连接点是通过什么方式退出的(正常返回或者抛出异常)都会在结束后执行这些Advice(@After 注解)
After Retuning(返回通知): 在连接点正常结束之后(没有抛出异常正常返回)执行的Advice(@AfterReturning 注解)
After Throwing(异常通知): 如果方法通过抛出异常来退出的话,这个Advice就会被执行(@AfterThrowing 注解)
Around(环绕通知):

5、在Spring AOP中关注点和横切关注点有什么不同?
关注点:我们在应用的模块中实现以解决特定业务问题的方法。比如库存管理、航运管理、用户管理等。

横切关注点:贯穿整个应用程序的关注点。像事务管理、权限、日志、安全等。

6、Spring AOP的代理是什么?
Spring AOP是基于代理实现的,默认为标准的 JDK 动态代理。这使得任何接口(或者接口的集合)可以被代理。
Spring AOP 也使用 CGLIB 代理。如果业务对象没有实现任何接口那么默认使用CGLIB。