Spring AOP原理(2)
Spring 容器注册AnnotationAwareAspectJAutoProxyCreator
流程
注册配置类,调用
refresh()
刷新容器。调用
registerBeanPostProcessors(beanFactory);
注册bean的后置处理器方便拦截bean的创建。- 先获取ioc容器中已经定义了的需要创建对象的所有BeanPostProcessor。
- 优先注册实现了PriorityOrdered接口的BeanPostProcessor。
- 再给容器中注册实现了Order接口的BeanPostProcessor。
- 注册没有实现优先级接口的BeanPostProcessor。
- 注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中:
- 创建internalAutoProxyCreator的BeanPostPostProcessor实例
- populateBean:给bean的各种属性赋值
- initializeBean:初始化bean
- invokeAwareMethods,处理Aware接口的方法回调
- applyBeanPostProcessorsBeforeInitialization()应用后置处理器的PostProcessorsBeforeInitialization()方法。
- invokeInitMethods(beanName, wrappedBean, mbd);
- applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
- BeanPostProcessor创建成功。
- 把BeanPostProcessor注册到BeanFactory中:
beanFactory.addBeanPostProcessor(postProcessor);
publicstaticvoidregisterBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext){//获得容器中所有的BeanPostPrcessor
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;
beanFactory.addBeanPostProcessor(newBeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors=newArrayList<>();
List<BeanPostProcessor> internalPostProcessors=newArrayList<>();
List<String> orderedPostProcessorNames=newArrayList<>();
List<String> nonOrderedPostProcessorNames=newArrayList<>();//分别将实现了PriorityOrdered接口,Order接口和没有实现接口的三种PostProcessor分类。for(String ppName: postProcessorNames){if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)){
BeanPostProcessor pp= beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
internalPostProcessors.add(pp);}}elseif(beanFactory.isTypeMatch(ppName, Ordered.class)){
orderedPostProcessorNames.add(ppName);}else{
nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors=newArrayList<>(orderedPostProcessorNames.size());for(String ppName: orderedPostProcessorNames){
BeanPostProcessor pp= beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors=newArrayList<>(nonOrderedPostProcessorNames.size());for(String ppName: nonOrderedPostProcessorNames){
BeanPostProcessor pp= beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);if(ppinstanceofMergedBeanDefinitionPostProcessor){
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(newApplicationListenerDetector(applicationContext));}
@OverridepublicvoidaddBeanPostProcessor(BeanPostProcessor beanPostProcessor){
Assert.notNull(beanPostProcessor,"BeanPostProcessor must not be null");// Remove from old position, if anythis.beanPostProcessors.remove(beanPostProcessor);// Track whether it is instantiation/destruction awareif(beanPostProcessorinstanceofInstantiationAwareBeanPostProcessor){this.hasInstantiationAwareBeanPostProcessors=true;}if(beanPostProcessorinstanceofDestructionAwareBeanPostProcessor){this.hasDestructionAwareBeanPostProcessors=true;}// Add to end of listthis.beanPostProcessors.add(beanPostProcessor);}
protected<T> TdoGetBean(final String name,@Nullablefinal Class<T> requiredType,@Nullablefinal Object[] args,boolean typeCheckOnly)throws BeansException{// Create bean instance.if(mbd.isSingleton()){
sharedInstance=getSingleton(beanName,()->{try{returncreateBean(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);}return(T) bean;}
protected ObjectdoCreateBean(final String beanName,final RootBeanDefinition mbd,final@Nullable Object[] args)throws BeanCreationException{// Instantiate the bean.
BeanWrapper instanceWrapper= null;if(mbd.isSingleton()){
instanceWrapper=this.factoryBeanInstanceCache.remove(beanName);}if(instanceWrapper== null){
instanceWrapper=createBeanInstance(beanName, mbd, args);}final Object bean= instanceWrapper.getWrappedInstance();
Class<?> beanType= instanceWrapper.getWrappedClass();if(beanType!= NullBean.class){
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){thrownewBeanCreationException(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.isTraceEnabled()){
logger.trace("Eagerly caching bean '"+ beanName+"' to allow for resolving potential circular references");}addSingletonFactory(beanName,()->getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.
Object exposedObject= bean;try{populateBean(beanName, mbd, instanceWrapper);
exposedObject=initializeBean(beanName, exposedObject, mbd);}return exposedObject;}
AnnotationAwareAspectJAutoProxyCreator的对普通bean的作用
- 每一个bean创建之前,调用
postProcessBeforeInstantiation();
关心MathCalculator和LogAspect的创建。- 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
- 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean或者是否是切面
- 判断是否需要跳过
- 获取候选的增强器。(切面里面的通知方法)
- 返回false
- 返回null
- 创建完对象后,调用
postProcessAfterInitialization();
- 获取当前bean的所有增强器(通知方法)
Object[] specificInterceptors
- 找到能在当前bean使用的增强器,(找到哪些方法可以切入当前方法)
- 获取到能在bean使用的增强器。
- 给增强器排序
- 获取当前bean的所有增强器(通知方法)
- 保存当前bean在advisedBeans中:
- 如果当前bean需要增强,创建当前bean的代理对象。
- 获取所有增强器
- 保存到proxyFactory
- 创建代理对象,Spring自动决定是创建jdk动态代理还是cglib的动态代理。
- 给容器中返回当前组件使用cglib增强了的代理对象。
- 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程。
@Overridepublic ObjectpostProcessBeforeInstantiation(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;}
@Overridepublic AopProxycreateAopProxy(AdvisedSupport config)throws AopConfigException{if(config.isOptimize()|| config.isProxyTargetClass()||hasNoUserSuppliedProxyInterfaces(config)){
Class<?> targetClass= config.getTargetClass();if(targetClass== null){thrownewAopConfigException("TargetSource cannot determine target class: "+"Either an interface or a target is required for proxy creation.");}if(targetClass.isInterface()|| Proxy.isProxyClass(targetClass)){returnnewJdkDynamicAopProxy(config);}returnnewObjenesisCglibAopProxy(config);}else{returnnewJdkDynamicAopProxy(config);}}