Skip to content

Commit babbaa7

Browse files
committed
Polish the code of 5th chapter
1 parent f4362eb commit babbaa7

22 files changed

+1011
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>thinking-in-spring</artifactId>
7+
<groupId>org.geekbang</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>dependency-lookup</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>org.geekbang</groupId>
17+
<artifactId>ioc-container-overview</artifactId>
18+
<version>1.0-SNAPSHOT</version>
19+
<scope>compile</scope>
20+
</dependency>
21+
</dependencies>
22+
23+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.geekbang.thinking.in.spring.dependency.lookup;
18+
19+
import org.springframework.beans.factory.BeanFactory;
20+
import org.springframework.beans.factory.HierarchicalBeanFactory;
21+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
22+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
23+
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
24+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25+
26+
/**
27+
* 层次性依赖查找示例
28+
*
29+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
30+
* @since
31+
*/
32+
public class HierarchicalDependencyLookupDemo {
33+
34+
public static void main(String[] args) {
35+
// 创建 BeanFactory 容器
36+
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
37+
// 将当前类 ObjectProviderDemo 作为配置类(Configuration Class)
38+
applicationContext.register(ObjectProviderDemo.class);
39+
40+
// 1. 获取 HierarchicalBeanFactory <- ConfigurableBeanFactory <- ConfigurableListableBeanFactory
41+
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
42+
// System.out.println("当前 BeanFactory 的 Parent BeanFactory : " + beanFactory.getParentBeanFactory());
43+
44+
// 2. 设置 Parent BeanFactory
45+
HierarchicalBeanFactory parentBeanFactory = createParentBeanFactory();
46+
beanFactory.setParentBeanFactory(parentBeanFactory);
47+
// System.out.println("当前 BeanFactory 的 Parent BeanFactory : " + beanFactory.getParentBeanFactory());
48+
49+
displayContainsLocalBean(beanFactory, "user");
50+
displayContainsLocalBean(parentBeanFactory, "user");
51+
52+
displayContainsBean(beanFactory, "user");
53+
displayContainsBean(parentBeanFactory, "user");
54+
55+
// 启动应用上下文
56+
applicationContext.refresh();
57+
58+
// 关闭应用上下文
59+
applicationContext.close();
60+
61+
}
62+
63+
private static void displayContainsBean(HierarchicalBeanFactory beanFactory, String beanName) {
64+
System.out.printf("当前 BeanFactory[%s] 是否包含 Bean[name : %s] : %s\n", beanFactory, beanName,
65+
containsBean(beanFactory, beanName));
66+
}
67+
68+
private static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
69+
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
70+
if (parentBeanFactory instanceof HierarchicalBeanFactory) {
71+
HierarchicalBeanFactory parentHierarchicalBeanFactory = HierarchicalBeanFactory.class.cast(parentBeanFactory);
72+
if (containsBean(parentHierarchicalBeanFactory, beanName)) {
73+
return true;
74+
}
75+
}
76+
return beanFactory.containsLocalBean(beanName);
77+
}
78+
79+
private static void displayContainsLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
80+
System.out.printf("当前 BeanFactory[%s] 是否包含 Local Bean[name : %s] : %s\n", beanFactory, beanName,
81+
beanFactory.containsLocalBean(beanName));
82+
}
83+
84+
private static ConfigurableListableBeanFactory createParentBeanFactory() {
85+
// 创建 BeanFactory 容器
86+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
87+
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
88+
// XML 配置文件 ClassPath 路径
89+
String location = "classpath:/META-INF/dependency-lookup-context.xml";
90+
// 加载配置
91+
reader.loadBeanDefinitions(location);
92+
return beanFactory;
93+
}
94+
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.geekbang.thinking.in.spring.dependency.lookup;
18+
19+
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
20+
import org.springframework.beans.factory.ObjectProvider;
21+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Primary;
24+
25+
/**
26+
* 通过 {@link ObjectProvider} 进行依赖查找
27+
*
28+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
29+
* @since
30+
*/
31+
public class ObjectProviderDemo { // @Configuration 是非必须注解
32+
33+
public static void main(String[] args) {
34+
// 创建 BeanFactory 容器
35+
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
36+
// 将当前类 ObjectProviderDemo 作为配置类(Configuration Class)
37+
applicationContext.register(ObjectProviderDemo.class);
38+
// 启动应用上下文
39+
applicationContext.refresh();
40+
// 依赖查找集合对象
41+
lookupByObjectProvider(applicationContext);
42+
lookupIfAvailable(applicationContext);
43+
lookupByStreamOps(applicationContext);
44+
45+
// 关闭应用上下文
46+
applicationContext.close();
47+
48+
}
49+
50+
private static void lookupByStreamOps(AnnotationConfigApplicationContext applicationContext) {
51+
ObjectProvider<String> objectProvider = applicationContext.getBeanProvider(String.class);
52+
// Iterable<String> stringIterable = objectProvider;
53+
// for (String string : stringIterable) {
54+
// System.out.println(string);
55+
// }
56+
// Stream -> Method reference
57+
objectProvider.stream().forEach(System.out::println);
58+
}
59+
60+
private static void lookupIfAvailable(AnnotationConfigApplicationContext applicationContext) {
61+
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
62+
User user = userObjectProvider.getIfAvailable(User::createUser);
63+
System.out.println("当前 User 对象:" + user);
64+
}
65+
66+
@Bean
67+
@Primary
68+
public String helloWorld() { // 方法名就是 Bean 名称 = "helloWorld"
69+
return "Hello,World";
70+
}
71+
72+
@Bean
73+
public String message() {
74+
return "Message";
75+
}
76+
77+
private static void lookupByObjectProvider(AnnotationConfigApplicationContext applicationContext) {
78+
ObjectProvider<String> objectProvider = applicationContext.getBeanProvider(String.class);
79+
System.out.println(objectProvider.getObject());
80+
}
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.geekbang.thinking.in.spring.dependency.lookup;
18+
19+
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
20+
import org.springframework.beans.BeansException;
21+
import org.springframework.beans.factory.BeanFactory;
22+
import org.springframework.beans.factory.ListableBeanFactory;
23+
import org.springframework.beans.factory.ObjectFactory;
24+
import org.springframework.beans.factory.ObjectProvider;
25+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
26+
27+
/**
28+
* 类型安全 依赖查找示例
29+
*
30+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
31+
* @since
32+
*/
33+
public class TypeSafetyDependencyLookupDemo {
34+
35+
public static void main(String[] args) {
36+
// 创建 BeanFactory 容器
37+
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
38+
// 将当前类 TypeSafetyDependencyLookupDemo 作为配置类(Configuration Class)
39+
applicationContext.register(TypeSafetyDependencyLookupDemo.class);
40+
// 启动应用上下文
41+
applicationContext.refresh();
42+
43+
// 演示 BeanFactory#getBean 方法的安全性
44+
displayBeanFactoryGetBean(applicationContext);
45+
// 演示 ObjectFactory#getObject 方法的安全性
46+
displayObjectFactoryGetObject(applicationContext);
47+
// 演示 ObjectProvider#getIfAvaiable 方法的安全性
48+
displayObjectProviderIfAvailable(applicationContext);
49+
50+
// 演示 ListableBeanFactory#getBeansOfType 方法的安全性
51+
displayListableBeanFactoryGetBeansOfType(applicationContext);
52+
// 演示 ObjectProvider Stream 操作的安全性
53+
displayObjectProviderStreamOps(applicationContext);
54+
55+
// 关闭应用上下文
56+
applicationContext.close();
57+
}
58+
59+
private static void displayObjectProviderStreamOps(AnnotationConfigApplicationContext applicationContext) {
60+
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
61+
printBeansException("displayObjectProviderStreamOps", () -> userObjectProvider.forEach(System.out::println));
62+
}
63+
64+
private static void displayListableBeanFactoryGetBeansOfType(ListableBeanFactory beanFactory) {
65+
printBeansException("displayListableBeanFactoryGetBeansOfType", () -> beanFactory.getBeansOfType(User.class));
66+
}
67+
68+
private static void displayObjectProviderIfAvailable(AnnotationConfigApplicationContext applicationContext) {
69+
ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
70+
printBeansException("displayObjectProviderIfAvailable", () -> userObjectProvider.getIfAvailable());
71+
}
72+
73+
private static void displayObjectFactoryGetObject(AnnotationConfigApplicationContext applicationContext) {
74+
// ObjectProvider is ObjectFactory
75+
ObjectFactory<User> userObjectFactory = applicationContext.getBeanProvider(User.class);
76+
printBeansException("displayObjectFactoryGetObject", () -> userObjectFactory.getObject());
77+
}
78+
79+
public static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
80+
printBeansException("displayBeanFactoryGetBean", () -> beanFactory.getBean(User.class));
81+
}
82+
83+
private static void printBeansException(String source, Runnable runnable) {
84+
System.err.println("==========================================");
85+
System.err.println("Source from :" + source);
86+
try {
87+
runnable.run();
88+
} catch (BeansException exception) {
89+
exception.printStackTrace();
90+
}
91+
}
92+
}

thinking-in-spring/ioc-container-overview/src/main/java/org/geekbang/thinking/in/spring/ioc/overview/domain/User.java

+7
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,11 @@ public String toString() {
5151
", name='" + name + '\'' +
5252
'}';
5353
}
54+
55+
public static User createUser() {
56+
User user = new User();
57+
user.setId(1L);
58+
user.setName("小马哥");
59+
return user;
60+
}
5461
}

thinking-in-spring/pom.xml

+22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
<modules>
1313
<module>ioc-container-overview</module>
14+
<module>spring-bean</module>
15+
<module>dependency-lookup</module>
1416
</modules>
1517

1618
<properties>
@@ -49,6 +51,11 @@
4951

5052
<!-- Spring 依赖 -->
5153
<dependencies>
54+
<!-- Spring IoC 核心依赖 -->
55+
<dependency>
56+
<groupId>org.springframework</groupId>
57+
<artifactId>spring-context</artifactId>
58+
</dependency>
5259

5360
<dependency>
5461
<groupId>org.springframework</groupId>
@@ -65,4 +72,19 @@
6572
<artifactId>spring-webflux</artifactId>
6673
</dependency>
6774
</dependencies>
75+
76+
<build>
77+
78+
<plugins>
79+
<plugin>
80+
<groupId>org.apache.maven.plugins</groupId>
81+
<artifactId>maven-compiler-plugin</artifactId>
82+
<configuration>
83+
<source>1.8</source>
84+
<target>1.8</target>
85+
</configuration>
86+
</plugin>
87+
</plugins>
88+
89+
</build>
6890
</project>
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>thinking-in-spring</artifactId>
7+
<groupId>org.geekbang</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>spring-bean</artifactId>
13+
<description>Spring Bean 基础</description>
14+
15+
<dependencies>
16+
<!-- Spring IoC 核心依赖 -->
17+
<dependency>
18+
<groupId>org.springframework</groupId>
19+
<artifactId>spring-context</artifactId>
20+
</dependency>
21+
22+
<!-- 复用 ioc-container-overview</artifactId> -->
23+
<dependency>
24+
<groupId>${groupId}</groupId>
25+
<artifactId>ioc-container-overview</artifactId>
26+
<version>${version}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.geekbang</groupId>
30+
<artifactId>ioc-container-overview</artifactId>
31+
<version>1.0-SNAPSHOT</version>
32+
<scope>compile</scope>
33+
</dependency>
34+
</dependencies>
35+
36+
37+
</project>

0 commit comments

Comments
 (0)