spring-aop原理

一、前提

本片文章会从源码角度介绍aop的原理;共分为5个小节,每个小节后会有总结;想直接看结果的可直接关注小结内容或这节关注最后的总结;如有理解有误,欢迎指教

二、从一个简单的aop例子说起

1、定义一个切面,切入点为MathCalculator类里的所有方法;

@Aspect
public class LogAspects {
	
	//抽取公共的切入点表达式
	@Pointcut("execution(public int com.aop.MathCalculator.*(..))")
	public void pointCut(){};
	
	//@Before在目标方法之前切入
	@Before("pointCut()")
	public void logStart(JoinPoint joinPoint){
		Object[] args = joinPoint.getArgs();
		System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
	}
	
	//@Before在目标方法之后切入
	@After("com.aop.LogAspects.pointCut()")
	public void logEnd(JoinPoint joinPoint){
		System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
	}
	
	//在目标方法(div)正常返回之后运行
	//JoinPoint一定要出现在参数表的第一位,否则会出现参数匹配异常
	@AfterReturning(value="pointCut()",returning="result")
	public void logReturn(JoinPoint joinPoint,Object result){
		System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
	}
	
	//在目标方法(div)出现异常以后运行
	@AfterThrowing(value="pointCut()",throwing="exception")
	public void logException(JoinPoint joinPoint,Exception exception){
		System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
	}
}

2、定义目标类MathCalculator;

public class MathCalculator {
	
	public int div(int i,int j){
		System.out.println("MathCalculator...div...");
		return i/j;	
	}
}

3、定义配置类,@EnableAspectJAutoProxy表示开启事务

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
	 
	//业务逻辑类加入容器中
	@Bean
	public MathCalculator calculator(){
		return new MathCalculator();
	}

	//切面类加入到容器中
	@Bean
	public LogAspects logAspects(){
		return new LogAspects();
	}
}

4、测试类

@Test
	public void test(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
		
		MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
		mathCalculator.div(1, 0);
	}

5、输出结果:

div运行。。。@Before:参数列表是:{[1, 0]}
MathCalculator...div...
div结束。。。@After
div异常。。。异常信息:{java.lang.ArithmeticException: / by zero}

java.lang.ArithmeticException: / by zero

可见,当执行到目标方法mathCalculator.div()时,会先执行前置通知-》目标方法-》后置通知-》异常通知

三、原理

1、@EnableAspectJAutoProxy注解作用

由上面的例子可见,aop实现依赖于这个注解@EnableAspectJAutoProxy,我们打开这个注解看一下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;
}

EnableAspectJAutoProxy中使用@import快速导入AspectJAutoProxyRegistrar,打开AspectJAutoProxyRegistrar看一下:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
		}
		if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
			AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
		}
	}

}

重点为AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)这行代码(下面的两个if判断不会走,注解@EnableAspectJAutoProxy里proxyTargetClass与exposeProxy两个属性默认false),跟进去如下:

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 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;
		}
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

上面代码主要是将AnnotationAwareAspectJAutoProxyCreator这个组件包装成beanDefinition然后注册到BeanDefinitionRegistry中;来捋一下AnnotationAwareAspectJAutoProxyCreator这个组件的继承关系:

AnnotationAwareAspectJAutoProxyCreator:
  		AnnotationAwareAspectJAutoProxyCreator
  			->AspectJAwareAdvisorAutoProxyCreator
  				->AbstractAdvisorAutoProxyCreator
  					->AbstractAutoProxyCreator
  							implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

SmartInstantiationAwareBeanPostProcessor是一个后置处理器BeanPostProcessor,这里现记载下来,后面会用到这个 BeanPostProcessor

小结:

1. @EnableAspectJAutoProxy注解利用@Import(AspectJAutoProxyRegistrar.class)给容器中导入AspectJAutoProxyRegistrar
2. 利用AspectJAutoProxyRegistrar自定义给容器中注册bean
3. 注册的bean为internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator(后置处理器)

2、refresh刷新容器

容器启动会加载所有的单实例bean以及需要aop增强的类;容器启动最核心的方法为refresh方法:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}
public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				resetCommonCaches();
			}
		}
	}
3、AnnotationAwareAspectJAutoProxyCreator创建过程

上节说到@EnableAspectJAutoProxy会给容器中导入一个组件叫AnnotationAwareAspectJAutoProxyCreator;AnnotationAwareAspectJAutoProxyCreator实质是一个BeanPostProcessors,而容器初始化的时候会创建这个组件,具体在registerBeanPostProcessors(beanFactory)方法创建,registerBeanPostProcessors作用为注册bean的后置处理器,拦截bean的创建,截取下主要代码:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// 1、获取所有的BeanPostProcessor
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 2、给容器中添加一个BeanPostProcessor
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		//3、定义各种BeanPostProcessor分类集合
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		//4、遍历所有的BeanPostProcessor,按类型将其装入各自的集合
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			//5、从beanFactory工厂获取BeanPostProcessor
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				//添加priorityOrdered类型的PostProcessors
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					//添加internal类型的PostProcessors
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				//添加ordered类型的PostProcessors
				orderedPostProcessorNames.add(ppName);
			}
			else {
				//添加其他类型的PostProcessors
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		...省略
	}

上面主要逻辑为获取所有的BeanPostProcessor,再给容器添加一个BeanPostProcessor,遍历BeanPostProcessor,按类型将BeanPostProcessor加入对应的集合中;核心在于beanFactory.getBean中如何获取bean,实则为创建BeanPostProcessor对象,然后保存在容器中;getBean方法如下:

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		return doGetBean(name, requiredType, null, false);
	}

doGetBean主要方法如下:

// 创建一个单事例Bean
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								//创建bean 
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

createBean主要逻辑:

try {
			// 创建代理类
			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);
		}

		// 创建bean实例
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);

resolveBeforeInstantiation(beanName, mbdToUse)方法是返回一个代理类的,需要aop增强的bean会被代理;我们这里是创建BeanPostProcessor,是不需要被代理的,所以会走下面的doCreateBean(beanName, mbdToUse, args)方法,真正的去创建一个bean;

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 创建bean 反射调用构造方法
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
		mbd.resolvedTargetType = beanType;

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 给bean里的属性赋值
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				// 调用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);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

来看一下重点步骤:
1、createBeanInstance(beanName, mbd, args)这里是真正的创建bean,里面是利用反射调用的构造方法,然后将bean初始化后包装成BeanWrapper,这里不是aop的重点,不做详细介绍
2、populateBean(beanName, mbd, instanceWrapper)这是给bean里的属性赋值(比如@Autowired以来的属性)
3、initializeBean(beanName, exposedObject, mbd)调用bean的初始化方法,什么是初始化方法?initializeBean方法主要逻辑如下?

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			// 给Aware接口实现类的属性赋值
			invokeAwareMethods(beanName, 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);
		}
		return wrappedBean;
	}

1、invokeAwareMethods():处理Aware接口的方法回调;比如实现XXXaware接口,就可以拿到对映的属性;参考ApplicationContextAware
2、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
3、invokeInitMethods();执行自定义的初始化方法,也就是调用afterPropertiesSet方法(需要实现InitializingBean接口)
4、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();

至此、AnnotationAwareAspectJAutoProxyCreator组件创建完毕;
小结:

1、创建ioc容器,调用refresh()刷新容器
2、执行registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建
  2.1、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
  2.2、给容器中加别的BeanPostProcessor
  2.3、优先注册实现了PriorityOrdered接口的BeanPostProcessor
  2.4、再给容器中注册实现了Ordered接口的BeanPostProcessor
  2.5、注册没实现优先级接口的BeanPostProcessor
  2.6注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中【AnnotationAwareAspectJAutoProxyCreator】
    2.6.1、创建Bean的实例
    2.6.2、populateBean;给bean的各种属性赋值
    2.6.3、initializeBean:初始化bean
      2.6.3.1、invokeAwareMethods():处理Aware接口的方法回调
      2.6.3.2、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
      2.6.3.3、invokeInitMethods();执行自定义的初始化方法
      2.6.3.4、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
   2.6.4、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功
  2.7、把BeanPostProcessor注册到BeanFactory中;

4、finishBeanFactoryInitialization创建剩下的单实例bean

在上一小节2中,ioc容器在registerBeanPostProcessors方法创建了所有的BeanPostProcessors,其中就包含AnnotationAwareAspectJAutoProxyCreator这个组件;这个组件的作用是拦截所有的bean创建,在bean创建之前判断该bean是否需要代理,如果需要,则创建代理对象;反正去真正的创建bean;

来看一下ioc容器初始化倒数第二部finishBeanFactoryInitialization方法,顾名思义,创建剩下的单实例bean,finishBeanFactoryInitialization如下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					return getEnvironment().resolvePlaceholders(strVal);
				}
			});
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

重点在beanFactory.preInstantiateSingletons();方法,创建所有的非懒加载的单实例bean,preInstantiateSingletons如下:

public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		// 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<String>(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)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

上诉主要逻辑为遍历获取容器中所有的Bean,依次创建对象getBean(beanName);实则为创建bean;而getBean(beanName)方法和我们上一节创建BeanPostProcessors是一样的,执行流程为getBean->doGetBean->createBean,主要看下createBean逻辑(与上一节的creteBean是一个方法)

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("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);
		}

		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

重点在resolveBeforeInstantiation方法,从上面的注释翻译看:“给BeanPostProcessors一个机会,一个可以返回代理类的机会”,如果能返回代理类,那么直接返回;如果不能 则调用下面doCreateBean方法真正的去创建bean实例;什么样的bean才能被代理呢!就是那些切面类、需要增强的类;
resolveBeforeInstantiation主要逻辑:

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) {
				// 应用bean的前置处理器
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
					// 应用bean的后置处理器
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

applyBeanPostProcessorsBeforeInstantiation做了如下操作:

  1. 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
  2. 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
  3. 是否需要跳过

重点在applyBeanPostProcessorsAfterInitialization这,应用bean的后置处理器在bean实例化之后;来看下applyBeanPostProcessorsAfterInitialization主要逻辑:

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}

循环调用BeanPostProcessors子类的postProcessAfterInitialization方法;BeanPostProcessors是一个接口,具体逻辑由自类实现;前面第一节我们说到@EnableAspectJAutoProxy会像容器中导入一个组件叫AbstractAutoProxyCreato(AnnotationAwareAspectJAutoProxyCreator的父类),而这个组件也是一个后置处理器,当执行到这个组件时,就会调用AbstractAutoProxyCreator的postProcessAfterInitialization方法,点进去看一下AbstractAutoProxyCreator的postProcessAfterInitialization方法:

小结:

1、finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的单实例bean
2、遍历获取容器中所有的Bean,依次创建对象getBean(beanName);getBean->doGetBean()
  2.1、创建bean;AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截;先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;只要创建好的Bean都会被缓存起来;
  2.2、createBean();创建bean;AnnotationAwareAspectJAutoProxyCreator 会在任何bean创建之前先尝试返回bean的实例
    2.2.1、resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用,如果不能就继续
      2.2.1.1、后置处理器先尝试返回对象; bean = applyBeanPostProcessorsBeforeInstantiation():
拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor;
就执行postProcessBeforeInstantiation
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
      2.2.1.2、doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;和BeanPostProcessors流程一样;


```java
@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

可以看到postProcessAfterInitialization主要逻辑为先从缓存中获取,获取不到直接调用wrapIfNecessary,从方法名看来“如果需要的话就包装”,点进去看一下:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (beanName != null && 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;
	}

前几个判断是从缓存中取,取到直接返回;再判断当前bean是否需要被代理;如果需要被代理的对象并且首次创建,前几个if不会走,直接看getAdvicesAndAdvisorsForBean方法;

@Override
	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

findEligibleAdvisors(beanClass, beanName)为给当前的bean找可用的Advisors,什么意思?就是根据切入点表达式==execution(public int com.aop.MathCalculator.*(…))==来计算你当前要创建的bean是否满足该表达式;如果不满足 返回return DO_NOT_PROXY则不需要创建,反之返回增强点;增强点就是@Before、@After、@AfterReturning和@AfterThrowing方法;

如果需要被代理,则会走到这行代码:

Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

createProxy方法:

protected Object createProxy(
			Class<?> beanClass, String beanName, 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());
	}

proxyFactory.getProxy最终会调用createAopProxy方法:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		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.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

如果是接口则使用jdk,否则使用cglib;至此会创建一个代理对象;(代理对象如何创建的详见这里)。

至此、ioc容器初始化完毕,所有的单实例bean和切面都创建完毕;当执行到目标方法时,实则执行的是代理类的方法,被cglib代理过的类都会进入CglibAopProxy的intercept方法;intercept方法如下:
小结:

postProcessAfterInitialization方法总结:return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
1、获取当前bean的所有增强器(通知方法)
2、保存当前bean在advisedBeans中;
3、如果当前bean需要增强,创建当前bean的代理对象;
  3.1、Spring自动决定 JdkDynamicAopProxy(config);jdk动态代理; ObjenesisCglibAopProxy(config);cglib的动态代理;
4、给容器中返回当前组件使用cglib增强了的代理对象;
5、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;

5、CglibAopProxy.intercept();拦截目标方法的执行
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Class<?> targetClass = null;
			Object target = null;
			try {
				if (this.advised.exposeProxy) {
					// Make invocation available if necessary.
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				// May be null. Get as late as possible to minimize the time we
				// "own" the target, in case it comes from a pool...
				target = getTarget();
				if (target != null) {
					targetClass = target.getClass();
				}
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				// Check whether we only have one InvokerInterceptor: that is,
				// no real advice, but just reflective invocation of the target.
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					// 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 = methodProxy.invoke(target, argsToUse);
				}
				else {
					// We need to create a method invocation...
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null) {
					releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}

this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);会将增强的方法以及原目标方法保存到一个链中(List),就是@Before、@After、@AfterReturning、@AfterThrowing、@Around标注的方法;当执行到proceed()时,就会依次执行到这些方法;

6、总结

1、 @EnableAspectJAutoProxy 开启AOP功能
2、@EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
3、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4、容器的创建流程:
  4.1、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
  4.2、finishBeanFactoryInitialization()初始化剩下的单实例bean
    4.2.1、创建业务逻辑组件和切面组件
    4.2.2、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
    4.2.3、组件创建完之后,判断组件是否需要增强是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
5、执行目标方法:
  5.1、代理对象执行目标方法
  5.2、CglibAopProxy.intercept();
    5.2.1、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
    5.2.2、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
    5.2.3、效果:
         正常执行:前置通知-》目标方法-》后置通知-》返回通知
         出现异常:前置通知-》目标方法-》后置通知-》异常通知

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值