说起大名鼎鼎的 Spring 框架,大家都知道 Spring 有两大核心概念,一个是 Spring IOC,另一个就是 Spring AOP,本文目的在于让大家了解到 Spring AOP 的实现原理,我会通过源码的分析来让大家看到 Spring 是怎么实现的 AOP。
一、什么是AOP
AOP(Aspect-OrientedProgramming) 意思是面向切面编程,可以说是 OOP(Object-Oriented Programming) 面向对象编程的补充和完善,相较于 OOP 的继承,多态和封装的概念,AOP 更多关注的是业务中分散的功能点,举个例子,系统中记录操作日志的功能,分散在各个不同的模块中,操作日志的记录和主要业务部分本身关联不大,但是用 OOP 实现,就不得抽象出一个记录操作记录的接口,然后各个模块实现它,而使用 AOP,将记录操作日志的动作抽象成一个切面,再通过面向切面编程,那么就可以不用编写很多的重复代码。
二、AOP的相关概念
- Aspect(切面):Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice
- PointCut(切点):表示一组 join point,这些 join point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方
- Join Point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,同时自身还可以嵌套其他的连接点
- Advice(增强):又叫通知,Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 join point 之前、之后还是代替执行的代码
- Target(目标对象):织入 Advice 的目标对象
- Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
三、Spring AOP的使用
了解了 AOP 的相关概念之后,现在我们开始使用 Spring 的 AOP,话不多说,直接上代码。首先创建一个 maven 工程,引入 Spring-context 依赖,版本为5.1.1RELEASE
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.1.RELEASE</version>
</dependency>
接着选用aspectj作为aop的实现语言,和spring整合起来
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
接下来,我全程都使用注解的形式来使用 Spring AOP,首先我创建一个配置类,开启aspectj的自动代理支持
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.ww")
public class Wconfig {
}
新建一个接口和接口的实现类
public interface Dao {
void query();
}
@Component
public class IndexDao implements Dao{
@Override
public void query() {
System.out.println("query......");
}
}
然后创建测试方法
//代表是一个切面
@Aspect
@Component
public class WAspect {
/**
* execution表达式
*/
@Pointcut("execution(* com.ww.dao.*.*(..))")
public void point(){
}
/**
* 在切点上进行前置通知
*/
@Before("point()")
public void beforeAd(){
System.out.println("before-------------");
}
}
创建测试方法
public class TestAspect {
public static void main(String[] args) {
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(Wconfig.class);
Dao dao = configApplicationContext.getBean(Dao.class);
dao.query();
}
}
执行测试方法之后,可以看到控制台上在打印 query 方法中的 query...之前,打印了 before------------
大家看到,在调用 query 方法之前,先调用了前置通知方法 beforeAd ,说明执行了 AOP 的操作,Spring 是通过动态代理和字节码技术来实现 AOP 操作的,接下来,我们就来深入源码,探究 Spring AOP 的实现原理。
四、Spring AOP源码分析
进入debug,可以看到通过 getBean
的调用后返回的是经过 JDK 动态代理的对象 JdkDynamicAopProxy,也就是说在 getBean
的过程中,我们的 dao 对象已经被代理了。
配置的 AOP 的类在 IOC 阶段就已经生成了一个代理类,那么这个代理类是什么时候产生的呢,先进入 AbstractApplicationContext 的 getBean
方法
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
//获取IoC容器中指定名称和类型的Bean
return getBean(requiredType, (Object[]) null);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
//处理好的bean实例
Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
if (resolved == null) {
throw new NoSuchBeanDefinitionException(requiredType);
}
return (T) resolved;
}
@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
//获得一个bean的holder,其实也就是获得了bean的名字和bean的实例
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
}
else if (parent != null) {
ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
if (args != null) {
return parentProvider.getObject(args);
}
else {
return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
}
}
return null;
}
@SuppressWarnings("unchecked")
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
Class<?> clazz = requiredType.getRawClass();
Assert.notNull(clazz, "Required type must have a raw Class");
//得到可能的beanName数组
String[] candidateNames = getBeanNamesForType(requiredType);
if (candidateNames.length > 1) {
List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
for (String beanName : candidateNames) {
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (!autowireCandidates.isEmpty()) {
candidateNames = StringUtils.toStringArray(autowireCandidates);
}
}
if (candidateNames.length == 1) {
String beanName = candidateNames[0];
//最终断点进入了这行,此时的getBean才是真正起作用的getBean
return new NamedBeanHolder<>(beanName, (T) getBean(beanName, clazz, args));
}
else if (candidateNames.length > 1) {
Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
for (String beanName : candidateNames) {
if (containsSingleton(beanName) && args == null) {
Object beanInstance = getBean(beanName);
candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
candidates.put(beanName, getType(beanName));
}
}
String candidateName = determinePrimaryCandidate(candidates, clazz);
if (candidateName == null) {
candidateName = determineHighestPriorityCandidate(candidates, clazz);
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance == null || beanInstance instanceof Class) {
beanInstance = getBean(candidateName, clazz, args);
}
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
}
if (!nonUniqueAsNull) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
}
}
return null;
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
//真正做事的getBean方法
return doGetBean(name, requiredType, args, false);
}
接下来我们就进入 doGetBean
方法来看看
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**
* 这个方法在初始化的时候会调用,在 getBean 的时候也会调用
* 为什么需要这么做呢?
* 也就是说spring在初始化的时候先获取这个对象
* 判断这个对象是否被实例化好了
* 从spring的bean容器中获取一个bean,由于spring中bean容器是一个map(singletonObjects)
* 所以你可以理解 getSingleton(beanName) 等于 beanMap.get(beanName)
* 需要说明的是在初始化时候调用一般都是返回null
*/
// 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
此时我用上了条件断点,限定 beanName 为 indexDao 时才进入 getSingleton
方法,我们来看这个方法
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//spring所有的bean被放在ioc容器中的地方,就是这个singletonObjects,这是一个concorrentHashMap。
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
可是我们在这只看到了 singletonObjects.get
方法,那么 singletonObject
里的 bean
是什么时候被设置进去的呢,找一下我们就知道,是在 addSingleton
这个方法的时候被设置进去的,这个方法在 DefaultSingletonBeanRegistry 注册器中
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
我将条件断点打在 singletonObjects.put
方法上,当条件断点走进来时,查看此时的方法调用栈,发现其实在 addSingleton
方法执行之前,代理类就已经被创建出来了
查看调用栈,我们找到了这段代码
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//创建bean,由此可见,代理类就是从这个方法中产生的,此时需要继续debug
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//关键部分,创建实例bean,看到do开头的方法,我们就知道,这是个干“实事”的方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
再次断点进去,这回由于篇幅原因,我就不放那么多的代码了,我只截取重要的部分
// Initialize the bean instance.
//从这里开始bean的初始化操作
//暴露的bean实例
Object exposedObject = bean;
try {
//填充bean
populateBean(beanName, mbd, instanceWrapper);
//初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
同样的,我只截取重要的部分放在这里,我们看到这里出现了 applyBeanPostProcessorsBeforeInitialization
和 applyBeanPostProcessorsAfterInitialization
两个方法,在 spring bean 的生命周期中分别起到了预初始化和初始化后方法的作用
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
现在我们把断点打在这里,执行完 applyBeanPostProcessorsBeforeInitialization
方法之后,我们看到此时还未产生代理类
此时我们就知道,代理类一定是在 applyBeanPostProcessorsAfterInitialization
方法中产生的
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//获得后置处理器,这时候我们来看一下一共获得了多少后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
我们看到第四个处理器,就是 aspectj 自动代理创建器,此时真相大白了,Spring AOP 的动态代理类就是从这个创建器中创建出来的,我们断点进到这个 processor 的 postProcessAfterInitialization
方法
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//获取缓存key,不重要
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//看名字的意思是在需要的时候包装,那么这个代理类最终应该就是从这里产生的
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//果然,创建代理的代码在这里
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//创建aop工厂
return getAopProxyFactory().createAopProxy(this);
}
//该方法主要逻辑是创建一个AOP工厂,默认工厂是DefaultAopProxyFactory,该类的createAopProxy方法则根据ProxyFactoryBean的一些属性来决定创建哪种代理
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//由于默认的proxyTargetClass属性为false,代码转到else中,所以Spring AOP默认是使用java的动态代理来创建的代理类
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//实现了类接口,就创建jdk代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
//
return new JdkDynamicAopProxy(config);
}
}
在 CreateProxy
方法返回一个 JDK 的代理之后,调用了 getProxy
方法获得一个代理类,我们来看看 JdkDynamicAopProxy 的实现
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
当返回了一个代理类之后,接下来代理类调用到具体方法的时候,实际调用的就是 JdkDynamicAopProxy 类中的 invoke
方法
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
//获取代理对象中的目标源对象,就相当于实现类
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
//返回结果的引用
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
//获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//获取代理要在目标方法执行前后切入的拦截器,执行动态拦截,需要关注此方法(spring的方法命名为什么那么长,因为它把方法要做的事情都写在方法名上了)
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
//如果代理对象没有拦截器,就直接执行目标对象中的方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//利用反射调用目标方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 创建一个方法执行器,加入拦截器链,开始按照顺序执行拦截器中的方法和目标对象中的方法
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 方法执行
retVal = invocation.proceed();
}
// Massage return value if necessary.
// 获取方法的返回类型
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
接下来我们来看在上面的步骤中需要关注的几个方法
org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
//获取方法缓存key
MethodCacheKey cacheKey = new MethodCacheKey(method);
//从缓存中获取方法信息
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
//如果缓存中没有方法信息,则查询代理对象需要被执行的拦截信息
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
//查询出来之后放入缓存中以便下次直接使用
this.methodCache.put(cacheKey, cached);
}
return cached;
}
org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
//通知注册器,spring会把所有配置好的通知通过通知注册器管理
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//从配置信息中获取通知对象
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
//切点通知
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
@Override
@Nullable
public Object proceed() throws Throwable {
//开始执行代理方法,包括通知中方法和目标对象中的实际方法
//判断当前代理是否有要执行的通知,没有的话执行目标代码
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
综上就是 Spring AOP 的详细执行流程了,最后我在此给出一张 Spring AOP 的执行时序图
五、结语
本文,我从什么是 AOP 开始,分别介绍了AOP的相关概念,Spring AOP 的使用,接着对 Spring 的源码进行了分析,看到了 Spring AOP 创建动态代理类的过程和执行 AOP 切面代码逻辑的过程,至此,本文也就结束了,如有错误和不足,还请大家多多指正,感谢大家的支持。