1. 单一类型依赖查找
单一类型依赖查找接口:BeanFactory
- 根据Bean名称查找:
getBean(String)
- 根据Bean类型查找:
- Bean实时查找:
getBean(Class)
- Spring 5.1 Bean延迟查找:
getBeanProvider(Class)
getBeanProvider(ResolvableType)
- 根据Bean名称 + 类型查找:
getBean(String, Class)
- Bean实时查找:
2. 集合类型依赖查找
集合类型依赖查找接口:ListableBeanFactory
- 根据Bean类型查找:
- 获取同类型Bean名称列表:
getBeanNamesForType(Class)
getBeanNamesForType(ResolvableType)
- 获取同类型Bean实例列表
getBeansOfTypoe(Class)
- 获取同类型Bean名称列表:
- 通过注解类型查找
- 获取标注类型Bean名称列表:
getBeanNamesForAnnotation(Class<? extends Annotation)
- 获取标注类型Bean实例列表:
getBeansWithAnnotation(Class<? extends Annotation>)
- 获取标注类型Bean名称列表:
3. 层次性依赖查找
层次性依赖查找接口:HierarchicalBeanFactory
- 父BeanFactory:
getParentBeanFactory()
- 层次性查找:
- 根据Bean名称查找:基于
containsLocalBean
方法实现 - 根据Bean类型查找实例列表:
- 单一类型:
BeanFactoryUtils#beanOfType()
- 集合类型:
BeanFactoryUtils#beansOfTyoeIncludingAncestors()
- 单一类型:
- 根据Java注解查找名称列表:
BeanFactoryUtils#beanNamesForTypeIncludingAncestors()
- 根据Bean名称查找:基于
从上图中可以看出,ConfigurableBeanFactory
是层次性的依赖查找的BeanFactory,而 ConfigurableListableBeanFactory
既是层次性的也是集合类型的依赖查找。
Spring中常用类的一些继承关系如下:
4. 延迟依赖查找
延迟依赖查找接口:ObjectFactory
,ObjectProvider
public class ObjectProviderDemo {
/**
* 方法名就是Bean的名称
*/
@Bean
@Primary // 必须加上这个,否则 applicationContext.getBeanProvider(String.class) 会报错
public String hello() {
return "hello world";
}
@Bean
public String leihou() {
return "leihou";
}
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(ObjectProviderDemo.class); // 这种情况下@Configuration注解不是必须的
applicationContext.refresh();
lookupByObjectProvider(applicationContext);
lookupIfAvailable(applicationContext);
lookupByStreamOps(applicationContext);
applicationContext.close();
}
private static void lookupByObjectProvider(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<String> beanProvider = applicationContext.getBeanProvider(String.class);
System.out.println(beanProvider.getObject());
}
private static void lookupIfAvailable(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<User> beanProvider = applicationContext.getBeanProvider(User.class);
User user = beanProvider.getIfAvailable(User::createUser); // 如果User这个Bean不存在,则使用 User.createUser()
System.out.println("当前 User 对象:" + user);
}
private static void lookupByStreamOps(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<String> beanProvider = applicationContext.getBeanProvider(String.class);
beanProvider.stream().forEach(System.out::println);
}
}
5. 安全依赖查找
依赖查找类型 | 代表实现 | 是否安全 |
---|---|---|
单一类型查找 | BeanFactory#getBean | 否 |
ObjectFactory#getObject | 否 | |
ObjectProvider#getIfAvailable | 是 | |
集合类型查找 | ListableBeanFactory#getBeansOfType | 是 |
ObjectProvider#stream | 是 |
-
BeanFactory#getBean()
会抛下面的异常NoSuchBeanDefinitionException
NoUniqueBeanDefinitionException
-
ObjectFactory#getObject()
会抛BeansException
6. 内建可查找的依赖
AbstractApplicationContext
内建可查找的依赖:
Bean名称 | Bean实例 | 使用场景 |
---|---|---|
environment | Environment 对象 | 外部化配置及Profiles |
systemProperties | java.util.Properties 对象 | Java系统属性 |
systemEnvironment | java.util.Map 对象 | 操作系统环境变量 |
messageSource | MessageSource 对象 | 国际化文案 |
lifecycleProcessor | LifecycleProcessor 对象 | Lifecycle Bean处理器 |
applicationEventMulticaster | ApplicationEventMulticaster 对象 | Spring事件广播器 |
internalConfigurationAnnotationProcessor | ConfigurationClassPostProcessor 对象 | 处理Spring配置类 |
internalAutowiredAnnotationProcessor | AutowiredAnnotationBeanPostProcessor 对象 | 处理 @Autowired 以及 @Value 注解 |
internalCommonAnnotationProcessor | CommonAnnotationBeanPostProcessor 对象 | (条件激活)处理JSR-250注解,如@PostConstruct 等 |
internalEventListenerProcessor | EventListenerMethodProcessor 对象 | 处理标注@EventListener 的Spring事件监听方法 |
internalEventListenerFactory | DefaultEventListenerFactory 对象 | @EventListener 事件监听方法适配为ApplicationListener |
internalPersistenceAnnotationProcessor | PersistenceAnnotationBeanPostProcessor 对象 | (条件激活)处理JPA注解场景 |
后面以 internal
开头的几个Bean其实完整的Bean名称是以 org.springframework.xx
开头的。
具体可以查看 AnnotationConfigUtils
:
7. 依赖查找中的经典异常
异常类型 | 触发条件(举例) | 场景举例 |
---|---|---|
NoSuchBeanDefinitionException | 当查找Bean在IoC容器中不存在 | BeanFactory#getBean() |
NoUniqueBeanDefinitionException | 类型依赖查找时,IoC容器存在多个Bean实例 | BeanFactory#getBean(Class) |
BeanInstantiationException | 当Bean对应的类型为非具体类时 | BeanFactory#getBean() |
BeanCreationException | 当 Bean 初始化过程中 | Bean初始化方法执行异常时 |
BeanDefinitionStoreException | 当BeanDefinition配置元信息非法时 | XML配置资源无法打开时 |