赞
踩
前面的博客我们已经介绍完了spring的依赖的查找和注入的方式,这篇博客我们主要介绍下spring的依赖的查找和注入的来源。
查找来源
Spring 內建 BeanDefintion
Spring 內建单例对象
上面的各种依赖都是在spring的生命周期的过程中,初始化的,这儿不做过多的赘述,后面的博客我们在详细的介绍。
注入来源
具体的代码如下:
package org.learn.spring.dependency.source; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.core.io.ResourceLoader; import javax.annotation.PostConstruct; // 依赖来源示例 // BeanFactory.class ResourceLoader.class ApplicationEventPublisher.class ApplicationContext.class 不能用于我们的getBean public class DependencySourceDemo { // 注入在 postProcessProperties 方法执行,早于 setter注入 也早于生命周期回调函数@PostConstruct @Autowired private BeanFactory beanFactory; @Autowired private ResourceLoader resourceLoader; @Autowired private ApplicationEventPublisher applicationEventPublisher; @Autowired private ApplicationContext applicationContext; @PostConstruct public void init() { System.out.println("beanFactory == applicationContext :" + (beanFactory == applicationContext)); System.out.println("beanFactory == applicationContext.getAutowireCapableBeanFactory() :" + (beanFactory == applicationContext.getAutowireCapableBeanFactory())); System.out.println("resourceLoader == applicationContext :" + (resourceLoader == applicationContext)); System.out.println("applicationEventPublisher == applicationContext :" + (applicationEventPublisher == applicationContext)); } @PostConstruct public void initByLookUp() { getBean(BeanFactory.class); getBean(ResourceLoader.class); getBean(ApplicationEventPublisher.class); getBean(ApplicationContext.class); } private <T> T getBean(Class<T> beanType) { try { return beanFactory.getBean(beanType); } catch (NoSuchBeanDefinitionException e) { System.err.println("当前类型:" + beanType.getName() + "无法在 BeanFactory 中查找!"); } return null; } public static void main(String[] args) { // 创建BeanFactory的容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); // 注册Configuration Class 配置类 -> Spring Bean applicationContext.register(DependencySourceDemo.class); // 启动应用上下文 applicationContext.refresh(); // 依赖查找 DependencySourceDemo Bean DependencySourceDemo demo = applicationContext.getBean(DependencySourceDemo.class); // 显示的关闭spring应用上下文 applicationContext.close(); } }
运行的结果如下:
这儿的对象我们称之为spring的非托管对象,那么是怎么注册的。具体的如下:
依赖对象
要素
要素
限制
要素
限制
具体的代码如下:
package org.learn.spring.dependency.source; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import javax.annotation.PostConstruct; // ResolvableDependency 作为依赖来源 // 这儿的依赖的注入只能是类型的依赖的注入 public class ResolvableDependencySourceDemo { @Autowired private String value; @PostConstruct public void init(){ System.out.println(value); } public static void main(String[] args) { // 创建BeanFactory的容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); // 注册Configuration Class 配置类 -> Spring Bean applicationContext.register(ResolvableDependencySourceDemo.class); applicationContext.addBeanFactoryPostProcessor(beanFactory -> { // 注册 Resolvable Dependency beanFactory.registerResolvableDependency(String.class, "Hello,World"); }); // 启动应用上下文 applicationContext.refresh(); // 显示的关闭spring应用上下文 applicationContext.close(); } }
要素
限制
具体的代码如下
user.id=1
usr.name=甘雨
user.resource=classpath:/META-INF/default.properties
package org.learn.spring.dependency.source; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.io.Resource; import javax.swing.text.StyleConstants; // 外部化配置作为依赖的来源 @PropertySource(value = "classpath:/META-INF/default.properties",encoding = "UTF-8") @Configuration public class ExternalConfigurationDependencySourceDemo { @Value("${user.id:-1}") private Long id; @Value("${usr.name:}") private String name; @Value("${user.resource:classpath:/META-INF/default.properties}") private Resource resource; public static void main(String[] args) { // 创建BeanFactory的容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); // 注册Configuration Class 配置类 -> Spring Bean applicationContext.register(ExternalConfigurationDependencySourceDemo.class); // 启动应用上下文 applicationContext.refresh(); // 依赖查找 ExternalConfigurationDependencySourceDemo Bean ExternalConfigurationDependencySourceDemo demo = applicationContext.getBean(ExternalConfigurationDependencySourceDemo.class); System.out.println("demo.id = " + demo.id); System.out.println("demo.name = " + demo.name); System.out.println("demo.resource = " + demo.resource); // 显示的关闭spring应用上下文 applicationContext.close(); } }
注册BeanDefinition
,具体的代码如下:
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); // 我们这儿所有的BeanDefinition的类型都是AbstractBeanDefinition AbstractBeanDefinition是所有的BeanDefinition的超类 if (beanDefinition instanceof AbstractBeanDefinition) { try { // 这儿会校验BeanDefinition,这儿我不会做过多的赘述,后面有专门的博客来做介绍 ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } // 先查找对应的BeanDefinition是否存在 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { // 如果存在的话,看看这个BeanDefinition是否可以被覆盖,如果可以被覆盖,就重新存入Map中去,springFramework默认是true,是可以被覆盖,在springboot这个值被被改成了false,这儿就会抛出异常。 if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { // 判断当前的BeanDefinition是否在创建中 if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { // 将对应的key为BeanName value的值为BeanDefinition存放到beanDefinitionMap 中去 this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); // 将对应的BeanName的Map进行更新 this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase // 如果没有创建就将key为BeanName value的值为BeanDefinition存放到beanDefinitionMap 中去 this.beanDefinitionMap.put(beanName, beanDefinition); // 将对应的BeanName存到beanDefinitionNames的List中去 this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
从上面的的代码我们可以知道BeanDefinition
是存在beanDefinitionMap
的Map中去,key 是beanName
,value
是BeanDefinition
。同时将beanName
存到beanDefinitionNames
的List中去。
注册单例对象,具体的代码如下:
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
// 走来调用的是父类的方法
super.registerSingleton(beanName, singletonObject);
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
clearByTypeCache();
}
可以看到我们走来调用的是父类的方法org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton
具体的代码如下:
@Override public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { Assert.notNull(beanName, "Bean name must not be null"); Assert.notNull(singletonObject, "Singleton object must not be null"); synchronized (this.singletonObjects) { // 先获取对应的单例对象,如果存在直接抛出异常 Object oldObject = this.singletonObjects.get(beanName); if (oldObject != null) { throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); } addSingleton(beanName, singletonObject); } } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { // 将这个单例的对象存到对应Map中去,key为beanName value为singletonObject this.singletonObjects.put(beanName, singletonObject); // 从singletonFactories中移出beanName this.singletonFactories.remove(beanName); // 从earlySingletonObjects中移出beanName this.earlySingletonObjects.remove(beanName); // 从registeredSingletons中添加beanName this.registeredSingletons.add(beanName); } }
从上面的代码我们可以知道单例的对象是添加singletonObjects
Map中key
为beanName
,value
是这个单例的对象。同时beanName
也会存到registeredSingletons
中去。
ResolvableDependency
最后是不受spring管理的对象,注册的过程如下:
@Override
public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
Assert.notNull(dependencyType, "Dependency type must not be null");
if (autowiredValue != null) {
// 是ObjectFactory 直接抛出异常
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
throw new IllegalArgumentException("Value [" + autowiredValue +
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
}
// 将对应的对象存到resolvableDependencies Map中去 key为dependencyType value为autowiredValue
this.resolvableDependencies.put(dependencyType, autowiredValue);
}
}
上面的代码就是将这个对象存到resolvableDependencies
存到Map中去,key为dependencyType
value为autowiredValue
。上面的就是所有的依赖的注入的来源。而依赖的查找只会BeanDefinition的和singletonObjects这两个,这部分源码后面在介绍。
否, 依赖查找的来源仅限于 Spring BeanDefinition 以及单例对象, 而依赖注入的来源还包括 Resolvable Dependency 以及@Value 所标注的外部化配置
可以的, 单例对象的注册与 BeanDefinition
不同, BeanDefinition
会被 ConfigurableListableBeanFactory#freezeConfiguration()
方法影响, 从而冻结注册, 单例对象则没有这个限制。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。