依赖查找

image-20211219232529366

单一依赖查找

image-20211219232553157

延迟查找

1
2
3
4
5
6
7
8
9
@Bean
@Primary
public String hello(){
return "hello";
}

@Bean String hi(){
return "hi";
}
1
2
3
4
5
public static void lookupByObjectProvider(AnnotationConfigApplicationContext context){
ObjectProvider<String> beanProvider = context.getBeanProvider(String.class);
// ObjectProvider#getObject() 只能在只有一个String类型的单例时可以获取?添加@Primary注解即可
System.out.println(beanProvider.getObject());
}

集合类型依赖查询

image-20211219234134445

层次性依赖查找

image-20211219234558854

1
2
3
4
5
6
7
8
HierarchicalBeanFactory 继承了 BeanFactory,所以此类支持单一类型依赖查找和层次类型查找
ConfigurableBeanFactory 继承了 HierarchicalBeanFactory,所以此类支持单一类型、层次类型依赖查找

ConfigurableListableBeanFactory 继承了 ConfigurableBeanFactory和 ListableBeanFactory 所以它支持单一类型、层次类型、集合类型依赖查找
DefaultListableBeanFactory 继承了 ConfigurableListableBeanFactory 所以它既是单一类型依赖查找,也是集合类型依赖查找,也是层次类型依赖查找

AbstractBeanFactory#containsBean(String) 会递归的遍历parentBeanFactory
AbstractBeanFactory#containsLocalBean(String)只会检查当前BeanFactory

延迟依赖查找

查找的时候创建注册?

image-20211220000334365`

1
2
3
4
5
6
7
8
9
10
11
/**
* 使用Lambda表达式
*
* @param context
*/
public static void lookupIfAvailable(AnnotationConfigApplicationContext context){
ObjectProvider<User> beanProvider = context.getBeanProvider(User.class);
// 提供一个兜底方案
User user = beanProvider.getIfAvailable(User::createUser);
System.out.println(user);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 使用 Stream API
*
* @param context
*/
public static void lookupStreamOps(AnnotationConfigApplicationContext context){
ObjectProvider<String> beanProvider = context.getBeanProvider(String.class);
// 1 ObjectProvider 实现了 Iterator
Iterator<String> iterator = beanProvider.iterator();
while (iterator.hasNext()) System.out.println(iterator.next());
// 2
beanProvider.stream().forEach(System.out::println);
}

安全依赖查找

什么是安全依赖查找,即是否查找会抛出NoSuchBeanDefinitionException – if there is no bean with the specified name
BeansException – if the bean could not be obtained

image-20211220205900489

内建可查找的依赖

从AnnotationConfigUtils源码中

image-20211220214441983

image-20211220214514771

依赖查找中的经典异常

image-20211220215738186

多个Bean实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class NoUniqueBeanDefinitionExceptionDemo {

public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(NoUniqueBeanDefinitionExceptionDemo.class);

try {
context.getBean(String.class);
} catch (NoUniqueBeanDefinitionException e) {
System.err.printf("String 类型的 Bean 存在 [%s] 个,具体信息:%s \n",
e.getNumberOfBeansFound(),e.getMessage());
}

context.close();
}

@Bean
public String bean1(){
return "bean1";
}

@Bean
public String bean2(){
return "bean2";
}
}

CharSequence是个接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class BeanInstantiationExceptionDemo {

public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();

BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CharSequence.class);

context.registerBeanDefinition("errorBean",beanDefinitionBuilder.getBeanDefinition());

// 启动时抛出异常
context.refresh();

context.close();
}
}

初始化过程中抛出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class BeanCreationExceptionDemo {

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(POJO.class);

context.registerBeanDefinition("errorBean", beanDefinitionBuilder.getBeanDefinition());

// 启动时抛出异常
context.refresh();

context.close();
}

static class POJO implements InitializingBean {

@PostConstruct
public void init() throws Exception {
throw new Exception("init Exception");
}

@Override
public void afterPropertiesSet() throws Exception {
throw new Exception("afterPropertiesSet Exception");
}
}
}