01 单一类型依赖查找
- 根据名称查询
- getBean(String)
- spring 2.5覆盖默认参数 getBean(string,object…)
- 根据类型查询
- Bean实时查找
- spring 3.0 getBean(class)
- spring 4.1覆盖默认参数getBean(Class,Object…)
- spring 5.1 bean延迟查找
- getBeanProvider(Class)
- getBeanProvider(ResolvableType)
- Bean实时查找
- 根据名称+类型查找
- getBean(String,Class)
02 集合类型依赖查找
- java.beans.beancontext.BeanContext
- ListableBeanFactory接口
- 根据bean类型查找
- 获取同类型bean名称列表
- getBeanNamesForType(Class)
- spring 4.2 getBeanNamesForType(ResolvableType)
- 获取同类型bean实例列表
- getBeansOfType(Class)以及重载方法
- 会导致bean被提前初始化,bean的不完全,可能会有错误
- 获取同类型bean名称列表
- 通过注解类型查找
- spring 3.0获取标注类型bean名称列表
- getBeanNamesForAnnotation(Class<? extend Annotation>)
- spring 3.0获取标注类型bean实例列表
- getBeanNamesWithAnnotation(Class<? extend Annotation>)
- spring 3.0获取指定名称+标注类型bean实例
- findAnnotationOnBean(String,Class<? extend Annotation>)
- spring 3.0获取标注类型bean名称列表
03 层次性依赖查找
- java.beans.beancontext.BeanContext
- HierarchicalBeanFactory
- 双亲 BeanFactory:getParentBeanFactory()
- 层次性查找
- 根据bean名称查
- 基于containsLocalBean方法实现
- 根据bean类型查找实例列表
- 单一类型 BeanFactoryUtils#beansOfType
- 集合类型 BeanFactoryUtils#beansOfTypeIncludingAncestors
- 根据Java注解查找名称列表
- BeanFactoryUtils#beanNamesForTypeIncludingAncestors
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59public class HierarchicalDependencyLookupDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 将当前类 ObjectProviderDemo 作为配置类(Configuration Class)
applicationContext.register(ObjectProviderDemo.class);
// 1. 获取 HierarchicalBeanFactory <- ConfigurableBeanFactory <- ConfigurableListableBeanFactory
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
System.out.println("当前 BeanFactory 的 Parent BeanFactory : " + beanFactory.getParentBeanFactory());
// 2. 设置 Parent BeanFactory
HierarchicalBeanFactory parentBeanFactory = createParentBeanFactory();
beanFactory.setParentBeanFactory(parentBeanFactory);
System.out.println("当前 BeanFactory 的 Parent BeanFactory : " + beanFactory.getParentBeanFactory());
displayContainsLocalBean(beanFactory, "user");
displayContainsLocalBean(parentBeanFactory, "user");
displayContainsBean(beanFactory, "user");
displayContainsBean(parentBeanFactory, "user");
// 启动应用上下文
applicationContext.refresh();
// 关闭应用上下文
applicationContext.close();
}
private static void displayContainsBean(HierarchicalBeanFactory beanFactory, String beanName) {
System.out.printf("当前 BeanFactory[%s] 是否包含 Bean[name : %s] : %s\n", beanFactory, beanName,
containsBean(beanFactory, beanName));
}
private static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
if (parentBeanFactory instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory parentHierarchicalBeanFactory = HierarchicalBeanFactory.class.cast(parentBeanFactory);
if (containsBean(parentHierarchicalBeanFactory, beanName)) {
return true;
}
}
return beanFactory.containsLocalBean(beanName);
}
private static void displayContainsLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
System.out.printf("当前 BeanFactory[%s] 是否包含 Local Bean[name : %s] : %s\n", beanFactory, beanName,
beanFactory.containsLocalBean(beanName));
}
private static ConfigurableListableBeanFactory createParentBeanFactory() {
// 创建 BeanFactory 容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
// XML 配置文件 ClassPath 路径
String location = "classpath:/META-INF/dependency-lookup-context.xml";
// 加载配置
reader.loadBeanDefinitions(location);
return beanFactory;
}
}04 延迟依赖查找
- BeanFactoryUtils#beanNamesForTypeIncludingAncestors
- ObjectFactory
- ObjectProvider
- getIfAvailable(Supplier)
- ifAvailable(Consumer)
- stream扩展
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45public class ObjectProviderDemo { // @Configuration 是非必须注解
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 将当前类 ObjectProviderDemo 作为配置类(Configuration Class)
applicationContext.register(ObjectProviderDemo.class);
// 启动应用上下文
applicationContext.refresh();
// 依赖查找集合对象
lookupByObjectProvider(applicationContext);
lookupIfAvailable(applicationContext);
lookupByStreamOps(applicationContext);
// 关闭应用上下文
applicationContext.close();
}
private static void lookupByStreamOps(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<String> objectProvider = applicationContext.getBeanProvider(String.class);
objectProvider.stream().forEach(System.out::println);
}
private static void lookupIfAvailable(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
User user = userObjectProvider.getIfAvailable(User::createUser);
System.out.println("当前 User 对象:" + user);
}
public String helloWorld() { // 方法名就是 Bean 名称 = "helloWorld"
return "Hello,World";
}
public String message() {
return "Message";
}
private static void lookupByObjectProvider(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<String> objectProvider = applicationContext.getBeanProvider(String.class);
System.out.println(objectProvider.getObject());
}
}05 安全依赖查找
- 单一类型
- BeanFactory#getBean 实时 不安全
- ObjectFactory#getObject 延迟 不安全
- ObjectProvider#getIfAvailable 延迟 安全
- 集合类型
- ListableBeanFactory#getBeansOfType 安全
- ObjectProvider#stream 安全
- DefaultListableBeanFactory 单一 集合 层次
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60public class TypeSafetyDependencyLookupDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 将当前类 TypeSafetyDependencyLookupDemo 作为配置类(Configuration Class)
applicationContext.register(TypeSafetyDependencyLookupDemo.class);
// 启动应用上下文
applicationContext.refresh();
// 演示 BeanFactory#getBean 方法的安全性
displayBeanFactoryGetBean(applicationContext);
// 演示 ObjectFactory#getObject 方法的安全性
displayObjectFactoryGetObject(applicationContext);
// 演示 ObjectProvider#getIfAvaiable 方法的安全性
displayObjectProviderIfAvailable(applicationContext);
// 演示 ListableBeanFactory#getBeansOfType 方法的安全性
displayListableBeanFactoryGetBeansOfType(applicationContext);
// 演示 ObjectProvider Stream 操作的安全性
displayObjectProviderStreamOps(applicationContext);
// 关闭应用上下文
applicationContext.close();
}
private static void displayObjectProviderStreamOps(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
printBeansException("displayObjectProviderStreamOps", () -> userObjectProvider.forEach(System.out::println));
}
private static void displayListableBeanFactoryGetBeansOfType(ListableBeanFactory beanFactory) {
printBeansException("displayListableBeanFactoryGetBeansOfType", () -> beanFactory.getBeansOfType(User.class));
}
private static void displayObjectProviderIfAvailable(AnnotationConfigApplicationContext applicationContext) {
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
printBeansException("displayObjectProviderIfAvailable", () -> userObjectProvider.getIfAvailable());
}
private static void displayObjectFactoryGetObject(AnnotationConfigApplicationContext applicationContext) {
// ObjectProvider is ObjectFactory
ObjectFactory<User> userObjectFactory = applicationContext.getBeanProvider(User.class);
printBeansException("displayObjectFactoryGetObject", () -> userObjectFactory.getObject());
}
public static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
printBeansException("displayBeanFactoryGetBean", () -> beanFactory.getBean(User.class));
}
private static void printBeansException(String source, Runnable runnable) {
System.err.println("==========================================");
System.err.println("Source from :" + source);
try {
runnable.run();
} catch (BeansException exception) {
exception.printStackTrace();
}
}
}06 内建可查找的依赖
- AbstractApplicationContext内建可查找的依赖
- Environment 外部配置以及Profiles
- systemProperties Java系统属性
- systemEnvironmnet 操作系统环境变量
- MessageSource 国际化文案
- LifecycleProcessor Lifecycle Bean 处理器
- ApplicationEventMulticaster spring事件广播器
- 注解驱动spring上下文内建可查找的依赖
- ConfigurationClassPostProcessor 处理spring配置类
- AutowiredAnnotationBeanPostProcessor 处理autowired及value注解
- CommonAnnotationBeanPostProcessor 条件激活 postContruct
- EventListenterMethodProcessor 处理eventListener注解标注的事件广播
- DefaultEventListenerFactory
- PersistenceAnnotationBeanPostProcessor 条件激活 处理jpa
07 依赖查找中的经典异常
- BeansException的子类
- NoSuchBeanDefinitionException
- NoUniqueBeanDefinitionException
- BeanCreationException
- BeanInstantiationException
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87public class BeanCreationExceptionDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 BeanDefinition Bean Class 是一个 POJO 普通类,不过初始化方法回调时抛出异常
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(POJO.class);
applicationContext.registerBeanDefinition("errorBean", beanDefinitionBuilder.getBeanDefinition());
// 启动应用上下文
applicationContext.refresh();
// 关闭应用上下文
applicationContext.close();
}
static class POJO implements InitializingBean {
// CommonAnnotationBeanPostProcessor
public void init() throws Throwable {
throw new Throwable("init() : For purposes...");
}
public void afterPropertiesSet() throws Exception {
throw new Exception("afterPropertiesSet() : For purposes...");
}
}
}
public class BeanInstantiationExceptionDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 BeanDefinition Bean Class 是一个 CharSequence 接口
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CharSequence.class);
applicationContext.registerBeanDefinition("errorBean", beanDefinitionBuilder.getBeanDefinition());
// 启动应用上下文
applicationContext.refresh();
// 关闭应用上下文
applicationContext.close();
}
}
public class NoUniqueBeanDefinitionExceptionDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 将当前类 NoUniqueBeanDefinitionExceptionDemo 作为配置类(Configuration Class)
applicationContext.register(NoUniqueBeanDefinitionExceptionDemo.class);
// 启动应用上下文
applicationContext.refresh();
try {
// 由于 Spring 应用上下文存在两个 String 类型的 Bean,通过单一类型查找会抛出异常
applicationContext.getBean(String.class);
} catch (NoUniqueBeanDefinitionException e) {
System.err.printf(" Spring 应用上下文存在%d个 %s 类型的 Bean,具体原因:%s%n",
e.getNumberOfBeansFound(),
String.class.getName(),
e.getMessage());
}
// 关闭应用上下文
applicationContext.close();
}
public String bean1() {
return "1";
}
public String bean2() {
return "2";
}
public String bean3() {
return "3";
}
}08 ObjectFactory-BeanFactory 区别
ObjectFactory与BeanFactory均提供依赖查找的能力
不过ObjectFactory仅关注一个或一种类型的bean依赖查询,并且自身不具备依赖查找的能力,由BeanFactory输出
BeanFactory则提供了单一类型,集合类型以及层次性等多种依赖查找方式