Spring后置处理器整理

3,353 阅读12分钟

Spring Bean的后置处理器扩展接口

1. BeanPostProcessor

都是在目标对象被实例化之后,并且属性也被设置之后调用的

  • postProcessBeforeInitialization
    • 在afterPropertiesSet或者自定义的初始化方法(使用@bean注解中的initMethod()属性或者使用xml配置)之前执行
  • postProcessAfterInitialization
    • 在afterPropertiesSet或者自定义的初始化方法之后执行(如果是从FactoryBean中获取的对象,则只有这个方法会起作用,,postProcessBeforeInitialization以及afterPropertiesSet或者自定义的初始化方法都不会有作用)

2. InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()方法的Object bean = resolveBeforeInstantiation(beanName, mbdToUse);方法里面执行了这个后置处理器

  • postProcessBeforeInstantiation
    • 在目标对象实例化之前调用,方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(一般都是代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
  • postProcessAfterInstantiation
    • 方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。如果该方法返回false,会忽略属性值的设置;如果返回true,会按照正常流程设置属性值。
  • postProcessPropertyValues
    • 方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法不会被调用。可以在该方法内对属性值进行修改
  • postProcessBeforeInitialization&postProcessAfterInitialization
    • 父接口BeanPostProcessor的2个方法

3. SmartInstantiationAwareBeanPostProcessor

智能实例化Bean后置处理器(继承InstantiationAwareBeanPostProcessor)

  • determineCandidateConstructors
    • 检测Bean的构造器,可以检测出多个候选构造器(Java好像只会确定唯一的备选的构造器)
  • getEarlyBeanReference
    • 循环引用的后置处理器,这个东西比较复杂, 获得提前暴露的bean引用。主要用于解决循环引用的问题,只有单例对象才会调用此方法
  • predictBeanType
    • 预测bean的类型,在最后的类型转化时会用到

4. MergedBeanDefinitionPostProcessor

  • postProcessMergedBeanDefinition
    • 缓存bean的注入信息的后置处理器,仅仅是缓存或者干脆叫做查找更加合适,没有完成注入,注入是另外一个后置处理器的作用(不实现这个方法,也能直接调用postProcessPropertyValues完成属性值的注入)

5. DestructionAwareBeanPostProcessor

  • postProcessBeforeDestruction

    • 在bean实例被销毁之前被调用

Spring Bean的扩展方法执行顺序

  • 实例化前:

    • InstantiationAwareBeanPostProcessor:postProcessBeforeInstantiation

    • AbstractAutowireCapableBeanFactory# createBean
      ...
      	Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      
  • 实例化:

    • SmartInstantiationAwareBeanPostProcessor:determineCandidateConstructors

    • AbstractAutowireCapableBeanFactory# createBeanInstance
      ...
        	 Constructor<?>[] ctors = 	determineConstructorsFromBeanPostProcessors(beanClass, beanName);
      
  • 属性赋值准备:

    • MergedBeanDefinitionPostProcessor:postProcessMergedBeanDefinition

    • AbstractAutowireCapableBeanFactory# doCreateBean
      ...
        	applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      
  • 属性赋值之前:

    • InstantiationAwareBeanPostProcessor:postProcessAfterInstantiation

    • AbstractAutowireCapableBeanFactory# doCreateBean
      ...
        	populateBean(beanName, mbd, instanceWrapper);
      
  • 属性赋值:

    • InstantiationAwareBeanPostProcessor:postProcessPropertyValues

    • AbstractAutowireCapableBeanFactory# doCreateBean
       ...
      	populateBean(beanName, mbd, instanceWrapper);
      
  • 初始化前:

    • BeanPostProcessor:postProcessBeforeInitialization

    • AbstractAutowireCapableBeanFactory# doCreateBean
      ...
        	exposedObject = initializeBean(beanName, exposedObject, mbd);
        
        	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
      
  • 初始化:

    • invokeInitMethods
     AbstractAutowireCapableBeanFactory# doCreateBean
     ...
    	exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    	invokeInitMethods(beanName, wrappedBean, mbd);
    
  • 初始化后:

    • BeanPostProcessor:postProcessAfterInitialization
    AbstractAutowireCapableBeanFactory# doCreateBean
     ...
    	exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    

Spring内部的后置处理器

内置BeanPostProcessor的加入时机

AnnotationConfigApplicationContext

  • 在实例化时,会注册6个Sprint内部的BeanDefinition, 里面包含了一个BeanFactory的后置处理器BeanFactoryPostProcessor(ConfigurationClassPostProcessor),三个bean的后置处理器BeanPostProcessor(AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor),但这时这三个类并没有加入到BeanPostProcessor的列表中,只是加入到Spring容器中

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    //		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    //		Assert.notNull(environment, "Environment must not be null");
    		this.registry = registry;
    		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    	}
    
    
    • org.springframework.context.annotation.ConfigurationClassPostProcessor
    • org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
    • org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
    • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
    • org.springframework.context.event.internalEventListenerProcessor
    • org.springframework.context.event.DefaultEventListenerFactory
  • AnnotationConfigApplicationContext在refresh()的*prepareBeanFactory()*方法中会加入两个内置的BeanPostProcessor:

    • org.springframework.context.support*.ApplicationContextAwareProcessor*
    • org.springframework.context.support.ApplicationListenerDetector
  • AnnotationConfigApplicationContext在refresh()的invokeBeanFactoryPostProcessors(beanFactory)方法中会调用容器所有的BeanFactoryPostProcessor接口的方法,在其内部实现类ConfigurationClassPostProcessor会主动注册一个BeanPostProcessor:

    • org.springframework.context.annotation.ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor
  • AnnotationConfigApplicationContext在*refresh()的registerBeanPostProcessors()*方法中中会主动从beanDefinitionMap中寻找BeanPostProcessors类型的bean,并进行注册,这个方法中如果没有开启额外的配置,会注入5个Spring内部的BeanPostProcessors:

    public static void registerBeanPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    			...
    	}
    

    一个是在方法最开始,默认加入的:

    • org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker

    三个bean是之前在AnnotationConfigApplicationContext初始化时,加入到Spring容器中的:

    • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
    • org.springframework.beans.factory.annotation*.AutowiredAnnotationBeanPostProcessor*
    • org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor

    一个是默认加入的(这个在prepareBeanFactory方法中已经加入过一次,重新加入,是为了将这个后置处理器放到整个后置处理器的最末端)

    • org.springframework.context.support.ApplicationListenerDetector

BeanPostProcessor的执行顺序

BeanPostProcessor的执行顺序,是按照BeanPostProcessor的实现类加入到BeanFactory的List beanPostProcessors列表里面的顺序。(beanFactory.addBeanPostProcessor(postProcessor)方法默认是先移除,后添加,保证后面重新添加的实现类只有一个,且放在列表的最后面)依次为:

  1. ApplicationContextAwareProcessor

  2. ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

  3. PostProcessorRegistrationDelegate.BeanPostProcessorChecker

  4. Spring内部扫描出来的BeanPostProcessor按照 priority > ordered > non 的顺序进行排列,但是在如果这个类实现了MergedBeanDefinitionPostProcessor接口,则会全部单独放在最后重新处理(就是MergedBeanDefinitionPostProcessor接口的实现类默认是属于Spring的内部类,会放在其他BeanPostProcessor接口实现类的后面执行)。Spirng内部处理时会分成四种类型priorityOrdered、 ordered以、noOrder以及internalPostProcessors(实现了MergedBeanDefinitionPostProcessor接口)进行分组处理。PriorityOrdered、 ordered以及noOrder只按有没有实现实现PriorityOrdered、 Ordered接口来划分,如果只是添加了@Priority或者@order注解,则不会被处理,还是会被分配到noOrder组里,而这个组最后并不会进行排序的操作,所以会出现顺序与注解值不匹配的情况。但是如果添加了@Priority或者@order注解,并且实现了MergedBeanDefinitionPostProcessor接口,则会按照注解以及接口中的顺序进行统一的排序,因为排序的实现类是AnnotationAwareOrderComparator,会读取接口以及注解中的信息。

    Spring内部的三个类都实现了MergedBeanDefinitionPostProcessor接口,优先级顺序如下:

    • CommonAnnotationBeanPostProcessor:PriorityOrdered(Ordered.LOWEST_PRECEDENCE - 3)
    • AutowiredAnnotationBeanPostProcessor:PriorityOrdered(Ordered.LOWEST_PRECEDENCE - 2)
    • RequiredAnnotationBeanPostProcessor: PriorityOrdered(Ordered.LOWEST_PRECEDENCE - 1)
  5. ApplicationListenerDetector:默认放在最后

ApplicationContextAwareProcessor

主要实现了BeanPostProcessor接口的postProcessBeforeInitialization的方法

  • postProcessBeforeInitialization的方法中处理Aware子类的注入(通过相对应的set方法进行注入),包括EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、AbstractApplicationContex

    public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    		AccessControlContext acc = null;
    
    		...
    		if (acc != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareInterfaces(bean);
    				return null;
    			}, acc);
    		}
    		else {
    			invokeAwareInterfaces(bean);
    		}
    		return bean;
    	}
    
  • 这个后置处理器是在AbstractApplicationContext类的refresh()中的prepareBeanFactory(beanFactory)子方法由框架自动加入的。

    	/**
    	 *
    	 * 配置其标准的特征,比如上下文的加载器ClassLoader和post-processors回调
    	 * Configure the factory's standard context characteristics,
    	 * such as the context's ClassLoader and post-processors.
    	 * @param beanFactory the BeanFactory to configure
    	 * 此处的beanFactory参数等于DefaultListableFactory
    	 */
    	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    		// Tell the internal bean factory to use the context's class loader etc.
    		beanFactory.setBeanClassLoader(getClassLoader());
    		//bean表达式解释器,后面说  能够获取bean当中的属性在前台页面
    		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    		//对象与string类型的转换   <property red="dao">
    		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
    		// Configure the bean factory with context callbacks.
    		//添加一个后置管理器
    		//ApplicationContextAwareProcessor
    		// 能够在bean中获得到各种*Aware(*Aware都有其作用)
    		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    		...
    	}
    
    

ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

  • postProcessBeforeInitialization的实现方法中会处理ImportAware类型的类,会为该类型的类注入引入类注解相关的元数据信息

    @Override
    		public Object postProcessBeforeInitialization(Object bean, String beanName)  {
    			if (bean instanceof ImportAware) {
    				ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
    				AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
    				if (importingClass != null) {
    					((ImportAware) bean).setImportMetadata(importingClass);
    				}
    			}
    			return bean;
    		}
    	}
    
  • 比较典型的应用是与redis缓存相关的RedisHttpSessionConfiguration类,该类会由@EnableRedisHttpSession注解引入到Spring容器中,通过这个后置处理器就可以获取当时添加@EnableRedisHttpSession注解这个类添加时所有注解的信息

    @Configuration
    @ComponentScan("cn.gov.zcy.paas.web.auth.interceptor")
    @EnableScheduling
    @EnableRedisHttpSession(cleanupCron = "0 0 3 31 1 ?")
    public class MvcInterceptorAutoConfiguration extends WebMvcConfigurerAdapter {
      ...
    }
    

CommonAnnotationBeanPostProcessor

实现了InstantiationAwareBeanPostProcessor接口

  • 是AnnotationConfigApplicationContext初始化时注入的6个内部bean之一

  • 主要处理*@Resource、@PostConstruct和@PreDestroy*注解的实现,@Resource的处理是由他自己完成,@PostConstruct和@PreDestroy这两个是由他的父类 InitDestroyAnnotationBeanPostProcessor完成

  • postProcessMergedBeanDefinition方法中,其父类InitDestroyAnnotationBeanPostProcessor会寻找@PostConstruct和@PreDestroy注解,他本身会寻找@Resource注解

    CommonAnnotationBeanPostProcessor
    @Override
    	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    		// 父类处理@PostConstruct和@PreDestroy注解
    		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    		// 处理@Resource注解
    		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    		metadata.checkConfigMembers(beanDefinition);
    	}
    	
    InitDestroyAnnotationBeanPostProcessor
    @Override
    	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    		//找出被@PostConstruct和@PreDestroy注解修饰的方法
    		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
    		// 去除重复,并注册到beanDefinition中
    		metadata.checkConfigMembers(beanDefinition);
    	}
    
  • @PostConstruct注解的方法会在InitDestroyAnnotationBeanPostProcessor类的postProcessBeforeInitialization中进行调用处理,@PreDestroy注解的方法会在InitDestroyAnnotationBeanPostProcessor类的postProcessBeforeDestruction中进行调用

    InitDestroyAnnotationBeanPostProcessor
    @Override
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    		try {
    			metadata.invokeInitMethods(bean, beanName);
    		}
    		...
    		return bean;
    	}
    @Override
    	public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    		try {
    			metadata.invokeDestroyMethods(bean, beanName);
    		}
    		...
    	}
    
  • @Resource注解是在CommonAnnotationBeanPostProcessor方法的 postProcessPropertyValues方法进行注入的,底层的方法和@Autowired基本相同,都是调用InjectionMetadata的inject方法进行注入

    • @Resource是Java JSR-250中引入的注解,默认是按照byName进行注入,也支持byType。@Resource里面两个属性namey以及type分别对应两种方式。@Resource注解在进行注入操作时,会先判断Spring容器中(singletonObjects和beanDefinitionNames)是不是存在对应的beanName,如果存在就会直接使用factory.getBean方法获取同名的bean进行注入,如果不存在,底层会使用@Autowired相同的方法,去按照先ByType,然后ByName的方式注入。
    • 使用@Resource注解也支持注入Map、list、以及Array等数据结构,但是要注意,注入这些类型时定义的名字一定要是Spring容器中(singletonObjects和beanDefinitionNames)不存在的名字,不然由于优先byName寻找,导致奇怪的问题(因为Java的泛型是假的泛型,所以转化时不会报错)
    CommonAnnotationBeanPostProcessor
    @Override
    	public PropertyValues postProcessPropertyValues(
    			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
    		//找出类中被@Resource注解的属性和方法
    		//else if (field.isAnnotationPresent(Resource.class))
    		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
    		try {
    			metadata.inject(bean, beanName, pvs);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
    		}
    	return pvs;
    	}
    

AutowiredAnnotationBeanPostProcessor

实现了SmartInstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor接口

  • 是AnnotationConfigApplicationContext初始化时注入的6个内部bean之一

  • 处理自动装配的注解,@Autowired,@Value,@Inject(JSR-330的注解,功能和使用方法与@Autowired相同)

  • 实现了SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法(不算上空实现,是Spring容器中唯一实现了该接口的类),确认选择用哪一个构造方法进行实例化bean,构造方法的选择主要是基于以下几点:

    1. 如果没有定义构造函数,则默认使用无参的构造函数
    2. 如果只有唯一一个默认函数,则使用唯一的构造函数
    3. 如果存在多个构造函数并且包含有@Autowird注解,则使用使用加了@Autowird注解的构造方法,如果有多个构造函数添加了@Autowird注解则会报错
    4. 如果存在多个构造函数并且都不带有@Autowird注解, 就默认使用无参的构造函数函数,不存在无参的构造函数时就会报错

    通过这个方法选择的构造方法如果是Java代码最多只会有一个(Kotlin支持定义PrimaryConstructor,所以有可能会选出两个构造方法Primary+default,但是Java不支持定义PrimaryConstructor,所以最多只会有一个 )

    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
    			throws BeanCreationException {
    		// 默认先尝试从缓存中获取
    		Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
      
    		if (candidateConstructors == null) {
    			// Fully synchronized resolution now...
    			synchronized (this.candidateConstructorsCache) {
    				candidateConstructors = this.candidateConstructorsCache.get(beanClass);
    				if (candidateConstructors == null) {
    					Constructor<?>[] rawCandidates;
    					try {
    						// 获取该类所有的构造方法
    						rawCandidates = beanClass.getDeclaredConstructors();
    					}catch...
    				
    					List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
    					Constructor<?> requiredConstructor = null;
    					Constructor<?> defaultConstructor = null;
    					// 好像只有Kotlin的方式可以使用,java不支持
    					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
    					int nonSyntheticConstructors = 0;
    					for (Constructor<?> candidate : rawCandidates) {
    						// Synthetic:由java编译器生成的(有synthetic标记的field和method是class内部使用的,正常的源代码里不会出现synthetic field)
    						if (!candidate.isSynthetic()) {
    							nonSyntheticConstructors++;
    						}
    						else if (primaryConstructor != null) {
    							continue;
    						}
    						AnnotationAttributes ann = findAutowiredAnnotation(candidate);
    						if (ann == null) {
    							Class<?> userClass = ClassUtils.getUserClass(beanClass);
    							if (userClass != beanClass) {
    								try {
    									Constructor<?> superCtor =
    											userClass.getDeclaredConstructor(candidate.getParameterTypes());
    									ann = findAutowiredAnnotation(superCtor);
    								}
    								catch (NoSuchMethodException ex) {
    									// Simply proceed, no equivalent superclass constructor found...
    								}
    							}
    						}
    						if (ann != null) {
    							if (requiredConstructor != null) {
    								throw new BeanCreationException(beanName,
    										"Invalid autowire-marked constructor: " + candidate +
    										". Found constructor with 'required' Autowired annotation already: " +
    										requiredConstructor);
    							}
    							boolean required = determineRequiredStatus(ann);
    							if (required) {
    								if (!candidates.isEmpty()) {
    									throw new BeanCreationException(beanName,
    											"Invalid autowire-marked constructors: " + candidates +
    											". Found constructor with 'required' Autowired annotation: " +
    											candidate);
    								}
    								requiredConstructor = candidate;
    							}
    							candidates.add(candidate);
    						}
    						else if (candidate.getParameterCount() == 0) {
    							defaultConstructor = candidate;
    						}
    					}
    
    					if (!candidates.isEmpty()) {
    						// Add default constructor to list of optional constructors, as fallback.
    						if (requiredConstructor == null) {
    							if (defaultConstructor != null) {
    								candidates.add(defaultConstructor);
    							}
    							else if (candidates.size() == 1 && logger.isWarnEnabled()) {
    								logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
    										"': single autowire-marked constructor flagged as optional - " +
    										"this constructor is effectively required since there is no " +
    										"default constructor to fall back to: " + candidates.get(0));
    							}
    						}
    						candidateConstructors = candidates.toArray(new Constructor<?>[0]);
    					}
    					else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
    						candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
    					}
    					else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
    							defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
    						candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
    					}
    					else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
    						candidateConstructors = new Constructor<?>[] {primaryConstructor};
    					}
    					else {
    						candidateConstructors = new Constructor<?>[0];
    					}
    					this.candidateConstructorsCache.put(beanClass, candidateConstructors);
    				}
    			}
    		}
    		return (candidateConstructors.length > 0 ? candidateConstructors : null);
    	}
    
  • postProcessMergedBeanDefinition方法寻找带有(@Autowired,@Value,@Inject)注解的bean,并缓存信息。会区分是属性注入还是方法注入,分别使用不同的对象封装(AutowiredFieldElement和AutowiredMethodElement)

  • postProcessPropertyValues方法,处理(@Autowired,@Value,@Inject)注解,实现属性的注入。AutowiredFieldElement和AutowiredMethodElement都重写了inject注入方法,会调用自己的。

    • 支持处理一些复杂的bean,比如说List,Map,数组, Spring会帮你找出某一个接口所有的实现类,注入到List、map或者数组中(map默认的key是beanName
    • 注入首先根据byType进行寻找注入,如果根据type找到符合的class多余一个,就根据byName,决定注入。(如果没有匹配的就会根据@Autowired的required属性,决定是否直接抛错)

RequiredAnnotationBeanPostProcessor

主要实现了InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法

  • 是AnnotationConfigApplicationContext初始化时注入的6个内部bean之一

  • 处理@Required注解,做必填性校验注解适用于 bean 属性的 setter 方法,并且它指示受影响的 bean 属性必须在XML配置文件中配置时被填充或者@autowired(@Resource...)在setter方法上,否则容器将抛出 BeanInitializationException 异常。

    • 只要被处理过,就可以满足要求,不需要一定要注入属性。下面这段代码,如果Spring容器中没有ChenDao这个bean,注入时为null,但因为加了@Autowired(required = false)注解,启动时不会报错,只会在调用 hello()方法时会出现空指针;但是如果没有@Autowired(required = false)的注解,只有@Required注解,那么启动时就会报 BeanInitializationException 异常
    public class ChenService{
    	@Required
    	@Autowired(required = false)
        public void setChenDao(ChenDao chenDao) {
            this.chenDao = chenDao;
        }
       public void hello() {
        	chenDao.hello();
        }
    }
    

AnnotationAwareAspectJAutoProxyCreator

  • 处理Aop

属性值注入方法:InjectionMetadata#inject