依赖查找的来源

查找来源

Bean 名称 配置元数据 备注
Spring BeanDefinition
Spring BeanDefinition @Bean public User user(){}
单例对象 API 实现

Spring 內建 BeanDefintion

Bean 名称 Bean 实例 使用场景
org.springframework.context.
annotation.internalConfigur
ationAnnotationProcessor
ConfigurationClassPostProcessor 对象 用来处理 Spring 配置类
org.springframework.context.
annotation.internalAutowire
dAnnotationProcessor
AutowiredAnnotationBeanPostProcessor 对象 处理 @Autowired 以及 @Value
注解(构造器代码里 add 了上述两个注解)
org.springframework.context.
annotation.internalCommonAn
notationProcessor
CommonAnnotationBeanPostProcessor 对象 (条件激活)处理 JSR-250 注解,
如 @PostConstruct 等
org.springframework.context.
event.internalEventListener
Processor
EventListenerMethodProcessor 对象 处理标注 @EventListener 的
Spring 事件监听方法(直接标注在方法上就行,无需实现 ApplicationListener 接口)
org.springframework.context.
event.internalEventListener
Factory
DefaultEventListenerFactory 对
@EventListener 事件监听方法适
配为 ApplicationListener
org.springframework.context.
annotation.internalPersiste
nceAnnotationProcessor
PersistenceAnnotationBeanPostProcessor 对象 (条件激活)处理 JPA 注解场景

相关代码

先在 xml 文件中配置以下内容(当前来说不用弄,直接跟源码就行)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/beans/spring-context.xsd">
  9. <context:annotation-config/>
  10. <context:component-scan base-package="mindartisan.blog.csdn.net.XXX"/>
  11. <bean id="user" class="com.mindartisan.spring.geek.ioc.overview.domain.User" autowire="byName">
  12. <property name="id" value="1"/>
  13. <property name="name" value="Steve"/>
  14. </bean>
  15. <bean id="superUser" class="com.mindartisan.spring.geek.ioc.overview.domain.SuperUser" parent="user"
  16. primary="true">
  17. <property name="address" value="北京"/>
  18. </bean>
  19. <!-- 延迟查找使用 -->
  20. <bean id="objectFactoryCreatingFactoryBean"
  21. class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
  22. <property name="targetBeanName" value="user"/>
  23. </bean>
  24. </beans>

再来看 AnnotationConfigUtils.class

  1. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
  2. BeanDefinitionRegistry registry, @Nullable Object source) {
  3. DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
  4. if (beanFactory != null) {
  5. if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
  6. beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
  7. }
  8. if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
  9. beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
  10. }
  11. }
  12. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  13. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  14. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  15. def.setSource(source);
  16. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  17. }
  18. if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  19. RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
  20. def.setSource(source);
  21. beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  22. }
  23. // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  24. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  25. RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
  26. def.setSource(source);
  27. beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  28. }
  29. // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
  30. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  31. RootBeanDefinition def = new RootBeanDefinition();
  32. try {
  33. def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
  34. AnnotationConfigUtils.class.getClassLoader()));
  35. }
  36. catch (ClassNotFoundException ex) {
  37. throw new IllegalStateException(
  38. "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
  39. }
  40. def.setSource(source);
  41. beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  42. }
  43. if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  44. RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  45. def.setSource(source);
  46. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  47. }
  48. if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  49. RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  50. def.setSource(source);
  51. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
  52. }
  53. return beanDefs;
  54. }

这些会处理上述说的内容

Spring 内建单例对象

Bean 名称 Bean 实例 使用场景
environment Environment 对象 外部化配置:Java 系统的属性,比如 -D 参数
Profiles:比如 dev、test
systemProperties java.util.Properties 对象 Java 系统属性、系统路径或目录
systemEnvironment java.util.Map 对象 操作系统的环境变量(主要指当前用户环境变量)
messageSource MessageSource 对象 国际化文案
lifecycleProcessor LifecycleProcessor 对象 Lifecycle Bean 处理器(Bean 生命周期)
applicationEventMulticaster ApplicationEventMulticaster 对象 事件广播

相关代码

AbstractApplicationContext.class

  1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  2. // 无关代码
  3. // Register default environment beans.
  4. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  5. beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  6. }
  7. if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  8. beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  9. }
  10. if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  11. beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  12. }
  13. }
  14. /**
  15. * Initialize the ApplicationEventMulticaster.
  16. * Uses SimpleApplicationEventMulticaster if none defined in the context.
  17. * @see org.springframework.context.event.SimpleApplicationEventMulticaster
  18. */
  19. protected void initApplicationEventMulticaster() {
  20. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  21. if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
  22. this.applicationEventMulticaster =
  23. beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
  24. if (logger.isTraceEnabled()) {
  25. logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
  26. }
  27. }
  28. else {
  29. this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
  30. beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
  31. if (logger.isTraceEnabled()) {
  32. logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
  33. "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
  34. }
  35. }
  36. }
  37. /**
  38. * Initialize the LifecycleProcessor.
  39. * Uses DefaultLifecycleProcessor if none defined in the context.
  40. * @see org.springframework.context.support.DefaultLifecycleProcessor
  41. */
  42. protected void initLifecycleProcessor() {
  43. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  44. if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
  45. this.lifecycleProcessor =
  46. beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
  47. if (logger.isTraceEnabled()) {
  48. logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
  49. }
  50. }
  51. else {
  52. DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
  53. defaultProcessor.setBeanFactory(beanFactory);
  54. this.lifecycleProcessor = defaultProcessor;
  55. beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
  56. if (logger.isTraceEnabled()) {
  57. logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
  58. "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
  59. }
  60. }
  61. }
  62. /**
  63. * Initialize the MessageSource.
  64. * Use parent's if none defined in this context.
  65. */
  66. protected void initMessageSource() {
  67. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  68. if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
  69. this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
  70. // Make MessageSource aware of parent MessageSource.
  71. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
  72. HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
  73. if (hms.getParentMessageSource() == null) {
  74. // Only set parent context as parent MessageSource if no parent MessageSource
  75. // registered already.
  76. hms.setParentMessageSource(getInternalParentMessageSource());
  77. }
  78. }
  79. if (logger.isTraceEnabled()) {
  80. logger.trace("Using MessageSource [" + this.messageSource + "]");
  81. }
  82. }
  83. else {
  84. // Use empty MessageSource to be able to accept getMessage calls.
  85. DelegatingMessageSource dms = new DelegatingMessageSource();
  86. dms.setParentMessageSource(getInternalParentMessageSource());
  87. this.messageSource = dms;
  88. beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
  89. if (logger.isTraceEnabled()) {
  90. logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
  91. }
  92. }
  93. }

依赖注入的来源

注入来源

Bean 名称 配置元数据 备注
Spring BeanDefinition
Spring BeanDefinition @Bean public User user(){}
Spring BeanDefinition BeanDefinitionBuilder
单例对象 API 实现
非 Spring 容器管理对象(非推广对象;游离对象) ResolvaleDependency
外部化配置 @Value 注解读取配置文件

代码示例

  1. /**
  2. * 依赖来源示例
  3. *
  4. * @author mindartisan.blog.csdn.net
  5. * @date
  6. */
  7. public class DependencySourceDemo {
  8. // 注入在 postProcessProperties 方法执行,早于 setter 注入,也早于 @PostConstrut
  9. @Autowired
  10. private BeanFactory beanFactory;
  11. @Autowired
  12. private ResourceLoader resourceLoader;
  13. @Autowired
  14. private ApplicationContext applicationContext;
  15. @Autowired
  16. private ApplicationEventPublisher applicationEventPublisher;
  17. @PostConstruct
  18. public void initByInjection() {
  19. System.out.println("beanFactory == applicationContext -> " + (beanFactory == applicationContext));
  20. System.out.println("beanFactory == applicationContext.getBeanFactory -> " + (beanFactory == applicationContext.getAutowireCapableBeanFactory()));
  21. System.out.println("resourceLoader == applicationContext -> " + (resourceLoader == applicationContext));
  22. System.out.println("applicationEventPublisher == applicationContext -> " + (applicationEventPublisher == applicationContext));
  23. }
  24. @PostConstruct
  25. public void initByLookUp() {
  26. getBean(BeanFactory.class);
  27. getBean(ApplicationContext.class);
  28. getBean(ResourceLoader.class);
  29. getBean(ApplicationEventPublisher.class);
  30. }
  31. public <T> T getBean(Class<T> beanType) {
  32. try {
  33. return beanFactory.getBean(beanType);
  34. } catch (NoSuchBeanDefinitionException e) {
  35. System.err.println("当前类型:" + beanType.getName() +" 无法在 BeanFactory 中查找!");
  36. }
  37. return null;
  38. }
  39. public static void main(String[] args) {
  40. // 创建 BeanFactory 容器
  41. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  42. // 注册 配置类(配置类也是 Spring 的 Bean)
  43. applicationContext.register(DependencySourceDemo.class);
  44. // 启动 Spring 应用上下文
  45. applicationContext.refresh();
  46. // 依赖查找 AnnotationDependencyFieldInjectionDemo bean
  47. DependencySourceDemo demoBean = applicationContext.getBean(DependencySourceDemo.class);
  48. // 关闭 Spring 应用上下文
  49. applicationContext.close();
  50. }
  51. }

此 demo 的含义是为了证明 resolvableDependencies中的 bean 不是依赖查找中的来源,而是依赖注入中的来源。

源码分析

AbstractApplicationContext#refresh() -> AbstractApplicationContext#prepareBeanFactory()

  1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  2. // 无关代码
  3. // BeanFactory interface not registered as resolvable type in a plain factory.
  4. // MessageSource registered (and found for autowiring) as a bean.
  5. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  6. beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  7. beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  8. beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  9. }

DefaultListableBeanFactory#registerResolvableDependency()

  1. @Override
  2. public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
  3. Assert.notNull(dependencyType, "Dependency type must not be null");
  4. if (autowiredValue != null) {
  5. if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
  6. throw new IllegalArgumentException("Value [" + autowiredValue +
  7. "] does not implement specified dependency type [" + dependencyType.getName() + "]");
  8. }
  9. this.resolvableDependencies.put(dependencyType, autowiredValue);
  10. }
  11. }

DefaultListableBeanFactory#resolveDependency() -> DefaultListableBeanFactory#doResolveDependency() -> DefaultListableBeanFactory#findAutowireCandidates():

  1. protected Map<String, Object> findAutowireCandidates(
  2. @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
  3. String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
  4. this, requiredType, true, descriptor.isEager());
  5. Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
  6. // 重点是这玩意:this.resolvableDependencies.entrySet()
  7. // 断点位置下一行
  8. for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
  9. Class<?> autowiringType = classObjectEntry.getKey();
  10. if (autowiringType.isAssignableFrom(requiredType)) {
  11. Object autowiringValue = classObjectEntry.getValue();
  12. autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
  13. if (requiredType.isInstance(autowiringValue)) {
  14. result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
  15. break;
  16. }
  17. }
  18. }

image.png

Spring容器管理和游离对象

来源 Spring Bean 对象 生命周期管理 配置元信息 使用场景 备注
Spring BeanDefinition 查找、注入
Spring 内建单例对象 × 查找、注入
Resolvable Dependency × × 注入

Spring BeanDefinition 作为依赖来源

通过 BeanDefinitionRegistry#registerBeanDefinition 传递 BeanDefinition

  1. /**
  2. * Register a new bean definition with this registry.
  3. * Must support RootBeanDefinition and ChildBeanDefinition.
  4. * @param beanName the name of the bean instance to register
  5. * @param beanDefinition definition of the bean instance to register
  6. * @throws BeanDefinitionStoreException if the BeanDefinition is invalid
  7. * @throws BeanDefinitionOverrideException if there is already a BeanDefinition
  8. * for the specified bean name and we are not allowed to override it
  9. * @see GenericBeanDefinition
  10. * @see RootBeanDefinition
  11. * @see ChildBeanDefinition
  12. */
  13. void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  14. throws BeanDefinitionStoreException;

源码分析

DefaultListableBeanFactory#registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

  1. @Override
  2. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  3. throws BeanDefinitionStoreException {
  4. Assert.hasText(beanName, "Bean name must not be empty");
  5. Assert.notNull(beanDefinition, "BeanDefinition must not be null");
  6. if (beanDefinition instanceof AbstractBeanDefinition) {
  7. try {
  8. // validate() 方法在 BeanDefinitionBuilder 中也使用了
  9. ((AbstractBeanDefinition) beanDefinition).validate();
  10. }
  11. catch (BeanDefinitionValidationException ex) {
  12. throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
  13. "Validation of bean definition failed", ex);
  14. }
  15. }
  16. // map 由来:private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
  17. BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
  18. if (existingDefinition != null) {
  19. if (!isAllowBeanDefinitionOverriding()) {
  20. throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
  21. }
  22. else if (existingDefinition.getRole() < beanDefinition.getRole()) {
  23. // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
  24. if (logger.isInfoEnabled()) {
  25. logger.info("Overriding user-defined bean definition for bean '" + beanName +
  26. "' with a framework-generated bean definition: replacing [" +
  27. existingDefinition + "] with [" + beanDefinition + "]");
  28. }
  29. }
  30. else if (!beanDefinition.equals(existingDefinition)) {
  31. if (logger.isDebugEnabled()) {
  32. logger.debug("Overriding bean definition for bean '" + beanName +
  33. "' with a different definition: replacing [" + existingDefinition +
  34. "] with [" + beanDefinition + "]");
  35. }
  36. }
  37. else {
  38. if (logger.isTraceEnabled()) {
  39. logger.trace("Overriding bean definition for bean '" + beanName +
  40. "' with an equivalent definition: replacing [" + existingDefinition +
  41. "] with [" + beanDefinition + "]");
  42. }
  43. }
  44. this.beanDefinitionMap.put(beanName, beanDefinition);
  45. }
  46. else {
  47. if (hasBeanCreationStarted()) {
  48. // Cannot modify startup-time collection elements anymore (for stable iteration)
  49. synchronized (this.beanDefinitionMap) {
  50. this.beanDefinitionMap.put(beanName, beanDefinition);
  51. List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
  52. updatedDefinitions.addAll(this.beanDefinitionNames);
  53. updatedDefinitions.add(beanName);
  54. this.beanDefinitionNames = updatedDefinitions;
  55. removeManualSingletonName(beanName);
  56. }
  57. }
  58. else {
  59. // Still in startup registration phase
  60. this.beanDefinitionMap.put(beanName, beanDefinition);
  61. // beanDefinitionNames 由来:
  62. /** List of bean definition names, in registration order. */
  63. // private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
  64. // beanDefinitionNames 作用:保证注册的顺序
  65. this.beanDefinitionNames.add(beanName);
  66. removeManualSingletonName(beanName);
  67. }
  68. this.frozenBeanDefinitionNames = null;
  69. }
  70. if (existingDefinition != null || containsSingleton(beanName)) {
  71. resetBeanDefinition(beanName);
  72. }
  73. }

注意:依赖注入阶段的延迟注入是用代理的方式;依赖查找是 bean 已经 ready 了,延迟非延迟没啥大区别

单例对象作为依赖来源

来源:外部的普通 Java 对象
注册方式:SingletonBeanRegistry#registerSingletion
限制:无生命周期管理以及无法延迟初始化 Bean(因为单体对象是外部已初始化对象,所以不存在 Lazy 的问题,Lazy 针对于 BeanDefinition,而非具体对象。)

源码分析

SingletonBeanRegistry#registerSingleton(String beanName, Object singletonObject) 由 DefaultSingletonBeanRegistry#registerSingleton(String beanName, Object singletonObject) 实现

  1. /** Cache of singleton objects: bean name to bean instance. */
  2. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  3. /** Cache of singleton factories: bean name to ObjectFactory. */
  4. private final Map<String, r<?>> singletonFactories = new HashMap<>(16);
  5. /** Cache of early singleton objects: bean name to bean instance. */
  6. private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
  7. /** Set of registered singletons, containing the bean names in registration order. */
  8. private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
  9. @Override
  10. public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
  11. Assert.notNull(beanName, "Bean name must not be null");
  12. Assert.notNull(singletonObject, "Singleton object must not be null");
  13. // 此处加锁是因为是一个二元操作:get、add
  14. synchronized (this.singletonObjects) {
  15. Object oldObject = this.singletonObjects.get(beanName);
  16. if (oldObject != null) {
  17. throw new IllegalStateException("Could not register object [" + singletonObject +
  18. "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
  19. }
  20. addSingleton(beanName, singletonObject);
  21. }
  22. }
  23. /**
  24. * Add the given singleton object to the singleton cache of this factory.
  25. * <p>To be called for eager registration of singletons.
  26. * @param beanName the name of the bean
  27. * @param singletonObject the singleton object
  28. */
  29. protected void addSingleton(String beanName, Object singletonObject) {
  30. // 此处加锁的原因是可能会被单独调用
  31. synchronized (this.singletonObjects) {
  32. this.singletonObjects.put(beanName, singletonObject);
  33. this.singletonFactories.remove(beanName);
  34. this.earlySingletonObjects.remove(beanName);
  35. this.registeredSingletons.add(beanName);
  36. }
  37. }

非Spring 容器管理对象作为依赖来源

限制:无生命周期管理、无法实现延迟初始化 bean、无法依赖查找(只能依赖注入)

源码分析

  1. /**
  2. * Resolvable Dependency 示例
  3. *
  4. * @author mindartisan.blog.csdn.net
  5. * @date
  6. */
  7. public class ResolvableDependencySourceDemo {
  8. @Autowired
  9. private String value;
  10. @PostConstruct
  11. public void init() {
  12. System.out.println(value);
  13. }
  14. public static void main(String[] args) {
  15. // 创建 BeanFactory 容器
  16. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  17. // 注册 配置类(配置类也是 Spring 的 Bean)
  18. applicationContext.register(ResolvableDependencySourceDemo.class);
  19. // 下行代码执行晚于 refresh 方法,可以 debug 发现
  20. // invokeBeanFactoryPostProcessors() 方法早于 bean 初始化「finishBeanFactoryInitialization()」之前
  21. applicationContext.addBeanFactoryPostProcessor(beanFactory -> beanFactory.registerResolvableDependency(String.class, "Hello,World"));
  22. // 启动 Spring 应用上下文
  23. applicationContext.refresh();
  24. // AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
  25. // if ((autowireCapableBeanFactory instanceof ConfigurableListableBeanFactory)) {
  26. // ConfigurableListableBeanFactory configurableListableBeanFactory = ConfigurableListableBeanFactory.class.cast(autowireCapableBeanFactory);
  27. // configurableListableBeanFactory.registerResolvableDependency(String.class, "Hello,World");
  28. // }
  29. // 关闭 Spring 应用上下文
  30. applicationContext.close();
  31. }
  32. }

总结:

注册非 Spring 管理的依赖对象时,可以通过两种方式实现:

  1. 通过 ApplicationContext.getBeanFactory() 获取 AnnotationConfigApplicationContext 创建时初始化的 DefaultListableBeanFactory 对象,然后调用 registryResolveableDependency 来注册,为啥不能通过 getAutowireCapableBeanFactory() 来获取beanFactory对象,因为方法中需要 beanFactory 已被激活即执行了 ApplicationContext的refresh() 操作之后
  2. 通过 addBeanFactoryPostProcessor 回调方式实现,因为当 refresh() 方法执行 invokeBeanFactoryPostProcessors() 时会遍历已创建的 beanFactoryPostProcessors 集合对象来执行 postProcessBeanFactory() 方法

外部化配置作为依赖来源

用到了 @Value注解,处理类似 @Autowired处理流程

相关代码:
ExternalConfigurationDependencySourceDemo.class

  1. /**
  2. * 外部化配置作为依赖来源 示例
  3. *
  4. * @author mindartisan.blog.csdn.net
  5. * @date
  6. */
  7. @Configuration
  8. @PropertySource(value = "META-INF/default.properties",encoding="UTF-8")
  9. public class ExternalConfigurationDependencySourceDemo {
  10. @Value("${user.id:-1}")
  11. private Long id;
  12. @Value("${usr.name}")
  13. private String name;
  14. @Value("${user.resource:classpath://default.properties}")
  15. private Resource resource;
  16. public static void main(String[] args) {
  17. // 创建 BeanFactory 容器
  18. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  19. // 注册 Configuration Class(配置类) -> Spring Bean
  20. applicationContext.register(ExternalConfigurationDependencySourceDemo.class);
  21. // 启动 Spring 应用上下文
  22. applicationContext.refresh();
  23. // 依赖查找 ExternalConfigurationDependencySourceDemo Bean
  24. ExternalConfigurationDependencySourceDemo demo = applicationContext.getBean(ExternalConfigurationDependencySourceDemo.class);
  25. System.out.println("demo.id = " + demo.id);
  26. System.out.println("demo.name = " + demo.name);
  27. System.out.println("demo.resource = " + demo.resource);
  28. // 显示地关闭 Spring 应用上下文
  29. applicationContext.close();
  30. }
  31. }

default.properties

  1. user.id = 1
  2. usr.name = mindartisan.blog.csdn.net
  3. user.resource = classpath://META-INF/default.properties

源码分析

DefaultListableBeanFactory#doResolveDependency()

  1. @Nullable
  2. public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
  3. @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
  4. // 无关代码
  5. Class<?> type = descriptor.getDependencyType();
  6. // 在下行代码处理注入的值
  7. Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
  8. if (value != null) {
  9. if (value instanceof String) {
  10. String strVal = resolveEmbeddedValue((String) value);
  11. BeanDefinition bd = (beanName != null && containsBean(beanName) ?
  12. getMergedBeanDefinition(beanName) : null);
  13. value = evaluateBeanDefinitionString(strVal, bd);
  14. }
  15. TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
  16. try {
  17. return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
  18. }
  19. catch (UnsupportedOperationException ex) {
  20. // A custom TypeConverter which does not support TypeDescriptor resolution...
  21. return (descriptor.getField() != null ?
  22. converter.convertIfNecessary(value, type, descriptor.getField()) :
  23. converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
  24. }
  25. }
  26. // 无关代码
  27. }