Spring注解版-面向切面

一、AOP功能注解使用步骤

  1. 使用@EnableAspectJAutoProxy注解开启SpringAOP功能;
  2. 使用@Aspect注解定义切面类, 使用@Before, @After, @AfterReturning, @AfterThrowing定义通知方法以及切点(可通过@Pointcut抽取公用的切入点表达式), 通知方法上第一个参数(且只能是第一个参数)可以写上JoinPoint joinPoint, Spring会自动注入连接点, 可通过连接点获取被增强方法的信息;
  3. 将被增强类和切面类都注册至IOC容器中
@Configuration
@EnableAspectJAutoProxy // 开启AOP
public class SpringAopConfig {
	@Bean // 注册切面
	public RoleAspect roleAspect() {
		return new RoleAspect();
	}
	@Bean // 注册被增强类
	public RoleServiceImpl roleServiceImpl() {
		return new RoleServiceImpl();
	}
}

@Aspect // 定义切面类 这里需要导入AspectJ的相关jar包才可以使用
public class RoleAspect {
	// 抽取公共的切入点表达式
	@Pointcut("execution(public int study.bryan.spring.service.impl.RoleServiceImpl.addRole(..))")
	public void pointcut() {
	}
	// 前置通知 被增强方法调用前, 前置通知被调用
	@Before("pointcut()")
	public void before(JoinPoint joinPoint) {	
		Object[] args = joinPoint.getArgs();		
		System.err.println("@Before....."+Arrays.toString(args));
	}	
	// 后置通知 无论被增强方法是否正常原型, 后置通知被调用
	@After(value = "pointcut()")
	public void after() {
		System.err.println("@After.....");
	}	
	// 返回通知 被增强方法正常运行返回后, 返回通知被调用 returning 指定通知方法里是哪个参数接收被增强方法的返回值
	@AfterReturning(value = "pointcut()", returning = "result")
	public void afterReturning(Object result) {	
		System.err.println("@AfterReturning....."+result);
	}
	// 异常通知 被增强方法出现异常, 异常通知被调用 throwing 指定通知方法哪个参数接收被增强方法抛出的异常
	@AfterThrowing(value = "pointcut()", throwing = "exception")
	public void afterThrowing(Exception exception) {
		System.err.println("@AfterThrowing....."+exception.getMessage());
	}
	// 还有一个环绕通知
}

// 被增强类
public class RoleServiceImpl {
	public int addRole(int i, int k) {
		int j = i/k;
		return j;
	}
}

二、@EnableAspectJAutoProxy: Spring何时注册AnnotationAwareAspectJAutoProxyCreator的Bean信息

  1. Spring通过@EnableAspectJAutoProxy注解开启AOP功能
  2. @EnableAspectJAutoProxy注解中被@Import注解标注, @Import中存在AspectJAutoProxyRegistrar类, 这个类实现了ImportBeanDefinitionRegistrar接口, 重写registerBeanDefinitions()方法;
  3. registerBeanDefinitions()方法中向Spring容器中注册了IDorg.springframework.aop.config.internalAutoProxyCreator,对象为AnnotationAwareAspectJAutoProxyCreator类的bean信息beanDefinition(只是注册bean信息, 还没有实例化);
  4. 在容器的refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory);方法里就是处理了关于@Import注解中所导入的类, 将这些类的信息注册至容器中(放进一个Map beanDefinitionMap中)
    部分源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
 // IOC学习部分讲解中 @Import用来向SpringIOC容器中注册Bean, AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口, 那么在重写的registerBeanDefinitions()就可以看出AspectJAutoProxyRegistrar向容器中注册了`ID`为`org.springframework.aop.config.internalAutoProxyCreator`,对象为`AnnotationAwareAspectJAutoProxyCreator`的类
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	....
}

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	/**
	 * 注册,扩展,和配置一个AspectJ的自动代理创建器
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		// 1. 传入注册器 调用 AopConfigUtils的方法注册bean
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		....其他源码
	}

}

public abstract class AopConfigUtils {
	// 这里定义了 自动代理创建器在容器中的ID值 常量 在注册的时候使用了
	public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
			"org.springframework.aop.config.internalAutoProxyCreator";
	.... 其他源码			
	// 2. 
	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
	}
	// 3. 可以看到这里就直接放入了一个AnnotationAwareAspectJAutoProxyCreator 类
	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
	.... 其他源码
	//	4. Class cls就是上面传入的AnnotationAwareAspectJAutoProxyCreator 类
	@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
		// 5. 传入cls创建一个BeanDefinition 用于存储Bean的信息 这里的cls就是AnnotationAwareAspectJAutoProxyCreator 
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		// 6. 最终看到调用注册方法 将AnnotationAwareAspectJAutoProxyCreator 注册至容器中, 且ID是AUTO_PROXY_CREATOR_BEAN_NAME ,也就是上面的常量
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}
	.... 其他源码
}

三、AnnotationAwareAspectJAutoProxyCreator的继承树
从继承树看出AnnotationAwareAspectJAutoProxyCreator是一个beanPostProcessor 后置处理器, 也是一个Aware, 只要分析出AnnotationAwareAspectJAutoProxyCreator作为Bean后置处理器时被Spring在何时使用, 作为Aware时被Spring何时使用, 就能大致分析出AnnotationAwareAspectJAutoProxyCreator怎么被实例化, 怎么为其他Bean创建代理对象;
Spring注解版-面向切面_第1张图片
四、Spring怎么将AnnotationAwareAspectJAutoProxyCreator实例化:
在容器的refresh()方法中的registerBeanPostProcessors()方法里处理所有需要实例化的Bean后置处理器, 而AnnotationAwareAspectJAutoProxyCreator就是一个BeanPostProcessor, 所以AnnotationAwareAspectJAutoProxyCreator就是再此时被Spring实例化

  1. 先获取IOC容器中已经定义了的需要创建的所有BeanPostProcessor;
  2. 给beanFactory中添加别的BeanPostProcessor;
  3. 循环所有的BeanPostProcessor, 调用getBean()实例化BeanPostProcessor, 然后分离BeanPostProcessor为三类, 其中在实例化的时候, 就会调用AnnotationAwareAspectJAutoProxyCreator作为Aware接口时的setBeanFactory()方法, 调用到initBeanFactory()方法用来初始化BeanFactoryAspectJAdvisorsBuilder(Aspect通知处理构造器);
  4. 完成实例化后将BeanPostProcessor注册至BeanFactory中,a.先注册实现了PriorityOrdered接口的BeanPostProcessor; b. 再注册实现了Ordered接口的BeanPostProcessor; c. 最后注册没有实现优先级接口的BeanPostProcessor; 其中AnnotationAwareAspectJAutoProxyCreator是实现了Ordered接口的;
    部分源码:
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		// 获取所有的需要实例化的Bean后置处理器
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		// 添加一些其他的Bean后置处理器
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
		// 将Bean后置处理器分离为三种
		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 调用getBean()实例化并初始化Bean后置处理器
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}
		// 分别处理三类Bean后置处理器, 将BeanPostProcessor放进BeanFactory的List beanPostProcessors中
		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

五、AnnotationAwareAspectJAutoProxyCreator在什么时候为bean创建代理:
在容器的refresh()方法中的finishBeanFactoryInitialization(beanFactory)方法里完成对beanFanctory的初始化, 会实例化剩余的单例Bean, 观察Bean实例化的整个周期可以发现原理;

  1. beanFactory.preInstantiateSingletons()方法中, 获取所有需要实例化的beanDefinitionNames, 循环这些Bean信息, 调用getBean()->doGetBean()->getSingleton()->createBean()来实例化bean;
	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}
		// 获取所有的beanDefinitionNames 已注册的BeanDefinition信息名称
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 循环 
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					// 调用getBean()实例化Bean
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							// 调用getBean()实例化Bean
							getBean(beanName);
						}
					}
				}
				else {
					// 调用getBean()实例化Bean
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		.... 其他源码
				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 在这里实例化Bean
							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);
				}
		.... 其他源码
		
	}
  1. createBean()方法中,resolveBeforeInstantiation()方法尝试使用Bean后置处理器拦截先创建一个代理Bean实例返回;
    1. resolveBeforeInstantiation()方法中调用bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);方法尝试返回bean;
    2. applyBeanPostProcessorsBeforeInstantiation()方法中循环IOC容器中已注册的所有实现了InstantiationAwareBeanPostProcessor接口的Bean后置处理器, 调用这些Bean后置处理器的postProcessBeforeInstantiation()方法; 而AnnotationAwareAspectJAutoProxyCreator恰好就是实现了InstantiationAwareBeanPostProcessor接口的类, 在其父类AbstractAutoProxyCreator中重写了postProcessBeforeInstantiation()方法;
    3. AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法中, 需要满足一定条件后就会为需要实例化的Bean创建代理Bean;
    4. 在创建代理Bean成功之后就直接调用AbstractAutoProxyCreator.postProcessAfterInitialization()方法,继续处理代理Bean, 然后直接返回Bean, 不在对Bean进行实例化,赋值属性,初始化等生命周期里的常规处理;
@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		.....其他源码
		try {
			// 在实例化Bean之前提前拦截 尝试使用BeanPostProcessors 去创建代理Bean, 成功则直接返回代理Bean
			// 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, 则调用doCreateBean()去实例化Bean
			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;
		}
		.....其他源码
	}

	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 调用applyBeanPostProcessorsBeforeInstantiation(), 这里面就调用了postProcessBeforeInstantiation()方法
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					// 如果Bean被实例化成功 则直接调用Bean后置处理器的BeanPostProcessorsAfterInitialization()方法
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
	
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			// 循环所有的InstantiationAwareBeanPostProcessor, 调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation();
			// 如果当前InstantiationAwareBeanPostProcessor刚好是AnnotationAwareAspectJAutoProxyCreator, 那么就会调用其父类 `AbstractAutoProxyCreator.postProcessBeforeInstantiation()`的方法去尝试创建代理Bean
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
		return null;
	}
  1. 如果resolveBeforeInstantiation()没有成功创建代理Bean, 则调用doCreateBean()真正实例化(调用Bean的构造器实例化)bean[createBeanInstance()],给bean属性赋值[populateBean()], 初始化bean[initializeBean()];
    1. initializeBean()方法中, 调用applyBeanPostProcessorsBeforeInitialization(), 在此方法中循环所有的Bean后置处理器, 调用Bean后置处理器的postProcessBeforeInitialization()方法;
    2. 接着调用invokeInitMethods()方法, 此方法中如果bean实现了InitializingBean接口,则调用bean重写的afterPropertiesSet()方法, 如果init-method属性指定了bean的初始化方法那么接着回调bean的初始化方法;
    3. 接着调用applyBeanPostProcessorsAfterInitialization()方法,此方法中循环所有Bean后置处理器, 调用Bean后置处理器的postProcessAfterInitialization()方法;而AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了BeanPostProcessorpostProcessAfterInitialization();SpringAbstractAutoProxyCreator.postProcessAfterInitialization()方法中为需要实例化的Bean创建代理Bean;
	// 实例化Bean的方法
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 在这里首次调用Bean构造器实例化Bean
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		.....其他源码....

		// Initialize the bean instance.
		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);
			}
		}
		.....其他源码....
		return exposedObject;
	}

	// 初始化Bean的方法
	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 如果Bean实现了Aware接口, 这里就会回调重写Aware接口的某些方法, 为Bean赋值一些Spring底层的组件
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 调用Bean后置处理器的BeanPostProcessorsBeforeInitialization()方法 处理Bean
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
		    // 回调Bean的初始化方法 如果Bean实现了`InitializingBean`接口,则调用`bean`重写的`afterPropertiesSet()`方法, 如果`init-method`属性指定了`bean`的初始化方法那么接着回调`bean`的初始化方法
			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()) {
			// 调用Bean后置处理器的BeanPostProcessorsAfterInitialization()方法 处理Bean
			// 在这里AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator重写了BeanPostProcessor的BeanPostProcessorsAfterInitialization(), 在重写的方法里为Bean创建了代理Bean
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

综上所述: AnnotationAwareAspectJAutoProxyCreatorSpring调用doCreateBean()方法将Bean实例化之前就拦截一次, 调用AbstractAutoProxyCreator.postProcessBeforeInstantiation()尝试创建代理Bean; 如果没有创建成功, 则在Bean实例化,属性复制, 初始化之后,调用AbstractAutoProxyCreator.postProcessAfterInitialization()方法创建代理Bean;

六、AnnotationAwareAspectJAutoProxyCreator如何为bean创建代理:
已知Spring会在Bean实例化之前调用AbstractAutoProxyCreator.postProcessBeforeInstantiation()尝试创建代理Bean, 已经在初始化后调用AbstractAutoProxyCreator.postProcessAfterInitialization()方法创建代理Bean, 那么分析这两个方法中是如何处理的, 就能知道Spring是如何为Bean创建代理Bean;

  1. AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法分析:
    1. 判断当前Bean是否已经在 advisedBeans(存放了所有被增强的代理Bean)中, 如果存在就返回null;
    2. 判断当前Bean是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean接口或者是否被@Aspect注解标注, 如果是则表示当前Bean是一个切面类, 那就返回Null;
    3. 判断是否应该跳过: 先获取容器中所有的通知Advisor, 如果这些通知存在一个是AspectJPointcutAdvisor, 那么需要跳过, 方法返回Null;
    4. 获取一个自定义的TargetSource, 如果TargetSource存在, 则通过TargetSource创建代理Bean;
@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}
  1. AbstractAutoProxyCreator.postProcessAfterInitialization()方法分析:
    1. 调用wrapIfNecessary()方法, 包装Bean;
    2. wrapIfNecessary()中, 先按postProcessBeforeInstantiation()方法前三点一样判断, 满足条件后往下走
    3. 获取符合当前Bean的所有增强器(通知方法)AdvisorsForBean: 也就是通过切入点表达式去匹配, 获取能够符合当前Bean的通知方法;
    4. 如果能够获取到符合当前Bean的增强器, 那么将当前Bean存入advisedBeans中, 标志已增强;然后调用createProxy()方法创建代理Bean;
    5. createProxy()方法中利用ProxyFactory 代理工厂创建代理Bean, 先将符合Bean的增强器Advisors注入至ProxyFactory , 然后调用proxyFactory.getProxy(getProxyClassLoader())方法;
    6. proxyFactory.getProxy()方法中先调用createAopProxy()方法根据规则返回一个AopProxy接口的代理工厂对象, 可能是CglibAopProxy,也可能是JdkDynamicAopProxy, 然后调用AopProxy接口的getProxy()方法为当前Bean创建代理对象, 最终给容器返回被增强后的代理对象;
    7. 之后在容器中获取Bean时, 容器返回的就是被增强后的代理Bean;
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				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;
		}
		// 获取符合当前Bean的增强器, 根据切入点表达式去匹配
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// 如果存在增强器, 则创建代理对象, 如果不存在增强器, 则不创建直接放回Bean
		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);
			}
		}
		// 获取符合当前Bean的增强器
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		// 将增强器注入代理工厂
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		// 创建代理工厂对象, 调用getProxy()创建代理Bean
		return proxyFactory.getProxy(getProxyClassLoader());
	}

	// 这段代码决定Spring是使用Cglib还是JDK来为Bean创建动态代理
	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (!IN_NATIVE_IMAGE &&
				(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.");
			}
			// 当前Bean是一个接口或者当前Bean继承了JDK的Proxy的动态代理,那么Spring就会选择适用JDK动态代理
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

七、增强器(通知方法)如何拦截代理对象的目标方法的执行:
已知Spring开启AOP功能之后,会为需要需要增强的Bean实例化一个代理对象, 之后每次从容器中获取Bean时,拿到的都是代理对象, 使用代理对象执行目标方法时, Spring会根据按照一定顺序执行通知方法;那么Spring是如何实现的拦截目标方法执行前后来执行通知方法的呢?

  1. 从容器中获取Bean, 可以发现容器返回是一个Cglib代理生成的代理对象
    Spring注解版-面向切面_第2张图片

  2. 当执行目标方法时, 会被CglibAopProxy&DynamicAdvisedInterceptor.intercept()方法拦截;

  3. 首先拦截方法中会根据目标对象和目标方法获取 拦截器链 List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 实际上这部分操作是将目标方法的所有增强器(通知方法)封装成MethodInterceptor集合

  4. 如果没有拦截器链, 则直接执行目标方法

  5. 如果有拦截器链, 则需要创建一个CglibMethodInvocation对象, 并调用CglibMethodInvocation.proceed()方法

    1. 通过proceed()方法触发所有通知方法和目标方法的调用
    2. proceed()方法中 有一个常量this.currentInterceptorIndex 用来代表当前拦截器链索引, 默认为-1,每次进入proceed()方法时this.currentInterceptorIndex都自增一次, 通过索引在之前封装的chain 中获取拦截器(其实就是增强器), 获取到拦截器后, 调用拦截器的invoke()方法, 在每个拦截器的invoke()方法中回调proceed(),且处理回调相关的通知方法;
    3. this.currentInterceptorIndex的值等于chain的长度-1时, 表示已经循环到最后的连接器链, 此时回调目标方法, 将目标方法的返回值返回;然后依次返回前一次调用的方法;
  6. 流程图:
    Spring注解版-面向切面_第3张图片

  7. 综上所述: SpringAOP通过CglibAopProxy来拦截目标方法的, 获取目标方法的所有增强器(通知方法), 将通知方法按一定顺序封装成MethodInterceptor(方法拦截器)集合, 形成一个拦截器链; 根据目标对象目标方法以及获取的拦截器链创建CglibMethodInvocation对象, 调用CglibMethodInvocation.proceed()方法, 类似递归一样,循环获取拦截器链来处理回调通知方法; 达到在目标方法前后能够执行各种通知方法的目的

    你可能感兴趣的:(Spring,spring,aop)