Skip to content

Commit 351488d

Browse files
Merge pull request mercyblitz#1 from mercyblitz/master
Chapter 10
2 parents 4a02523 + ed73d6b commit 351488d

File tree

60 files changed

+3258
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+3258
-6
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,8 @@ license-list
4141
# grpc compiler
4242
compiler/gradle.properties
4343
compiler/build/*
44-
compiler/.gradle/*
44+
compiler/.gradle/*
45+
46+
47+
# Tomcat
48+
.extract
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<artifactId>thinking-in-spring</artifactId>
8+
<groupId>org.geekbang</groupId>
9+
<version>1.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<groupId>org.example</groupId>
13+
<artifactId>bean-lifecycle</artifactId>
14+
<version>1.0-SNAPSHOT</version>
15+
16+
<dependencies>
17+
18+
<dependency>
19+
<groupId>org.geekbang</groupId>
20+
<artifactId>ioc-container-overview</artifactId>
21+
<version>1.0-SNAPSHOT</version>
22+
<scope>compile</scope>
23+
</dependency>
24+
25+
</dependencies>
26+
27+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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.bean.lifecycle;
18+
19+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
20+
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
21+
22+
/**
23+
* 注解 BeanDefinition 解析示例
24+
*
25+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
26+
* @since
27+
*/
28+
public class AnnotatedBeanDefinitionParsingDemo {
29+
30+
public static void main(String[] args) {
31+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
32+
// 基于 Java 注解的 AnnotatedBeanDefinitionReader 的实现
33+
AnnotatedBeanDefinitionReader beanDefinitionReader = new AnnotatedBeanDefinitionReader(beanFactory);
34+
int beanDefinitionCountBefore = beanFactory.getBeanDefinitionCount();
35+
// 注册当前类(非 @Component class)
36+
beanDefinitionReader.register(AnnotatedBeanDefinitionParsingDemo.class);
37+
int beanDefinitionCountAfter = beanFactory.getBeanDefinitionCount();
38+
int beanDefinitionCount = beanDefinitionCountAfter - beanDefinitionCountBefore;
39+
System.out.println("已加载 BeanDefinition 数量:" + beanDefinitionCount);
40+
// 普通的 Class 作为 Component 注册到 Spring IoC 容器后,通常 Bean 名称为 annotatedBeanDefinitionParsingDemo
41+
// Bean 名称生成来自于 BeanNameGenerator,注解实现 AnnotationBeanNameGenerator
42+
AnnotatedBeanDefinitionParsingDemo demo = beanFactory.getBean("annotatedBeanDefinitionParsingDemo",
43+
AnnotatedBeanDefinitionParsingDemo.class);
44+
System.out.println(demo);
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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.bean.lifecycle;
18+
19+
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
20+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
21+
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
22+
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
23+
import org.springframework.context.support.ClassPathXmlApplicationContext;
24+
25+
/**
26+
* Bean 初始化生命周期示例
27+
*
28+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
29+
* @since
30+
*/
31+
public class BeanInitializationLifecycleDemo {
32+
33+
public static void main(String[] args) {
34+
35+
executeBeanFactory();
36+
37+
}
38+
39+
private static void executeBeanFactory() {
40+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
41+
// 添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
42+
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
43+
// 添加 CommonAnnotationBeanPostProcessor 解决 @PostConstruct
44+
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
45+
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
46+
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
47+
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
48+
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
49+
// 显示地执行 preInstantiateSingletons()
50+
// SmartInitializingSingleton 通常在 Spring ApplicationContext 场景使用
51+
// preInstantiateSingletons 将已注册的 BeanDefinition 初始化成 Spring Bean
52+
beanFactory.preInstantiateSingletons();
53+
54+
// 通过 Bean Id 和类型进行依赖查找
55+
User user = beanFactory.getBean("user", User.class);
56+
System.out.println(user);
57+
58+
User superUser = beanFactory.getBean("superUser", User.class);
59+
System.out.println(superUser);
60+
61+
// 构造器注入按照类型注入,resolveDependency
62+
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
63+
64+
System.out.println(userHolder);
65+
66+
}
67+
68+
}
69+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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.bean.lifecycle;
18+
19+
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
20+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
21+
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
22+
import org.springframework.context.support.ClassPathXmlApplicationContext;
23+
24+
/**
25+
* Bean 实例化生命周期示例
26+
*
27+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
28+
* @since
29+
*/
30+
public class BeanInstantiationLifecycleDemo {
31+
32+
public static void main(String[] args) {
33+
executeBeanFactory();
34+
35+
System.out.println("--------------------------------");
36+
37+
executeApplicationContext();
38+
}
39+
40+
private static void executeBeanFactory() {
41+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
42+
// 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
43+
// beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
44+
// 方法二:将 MyInstantiationAwareBeanPostProcessor 作为 Bean 注册
45+
// 基于 XML 资源 BeanDefinitionReader 实现
46+
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
47+
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
48+
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
49+
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
50+
// 通过 Bean Id 和类型进行依赖查找
51+
User user = beanFactory.getBean("user", User.class);
52+
System.out.println(user);
53+
54+
User superUser = beanFactory.getBean("superUser", User.class);
55+
System.out.println(superUser);
56+
57+
// 构造器注入按照类型注入,resolveDependency
58+
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
59+
System.out.println(userHolder);
60+
}
61+
62+
private static void executeApplicationContext() {
63+
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
64+
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
65+
applicationContext.setConfigLocations(locations);
66+
// 启动应用上下文
67+
applicationContext.refresh();
68+
69+
User user = applicationContext.getBean("user", User.class);
70+
System.out.println(user);
71+
72+
User superUser = applicationContext.getBean("superUser", User.class);
73+
System.out.println(superUser);
74+
75+
// 构造器注入按照类型注入,resolveDependency
76+
UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);
77+
System.out.println(userHolder);
78+
79+
// 关闭应用上下文
80+
applicationContext.close();
81+
82+
}
83+
84+
85+
}
86+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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.bean.lifecycle;
18+
19+
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
20+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
21+
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
22+
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
23+
24+
/**
25+
* TODO
26+
*
27+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
28+
* @since
29+
*/
30+
public class BeanLifecycleDemo {
31+
32+
public static void main(String[] args) throws InterruptedException {
33+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
34+
// 添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
35+
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
36+
// 添加 MyDestructionAwareBeanPostProcessor 执行销毁前回调
37+
beanFactory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
38+
// 添加 CommonAnnotationBeanPostProcessor 解决 @PostConstruct @PreDestroy
39+
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
40+
41+
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
42+
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
43+
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
44+
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
45+
// 显示地执行 preInstantiateSingletons()
46+
// SmartInitializingSingleton 通常在 Spring ApplicationContext 场景使用
47+
// preInstantiateSingletons 将已注册的 BeanDefinition 初始化成 Spring Bean
48+
beanFactory.preInstantiateSingletons();
49+
50+
// 通过 Bean Id 和类型进行依赖查找
51+
User user = beanFactory.getBean("user", User.class);
52+
System.out.println(user);
53+
54+
User superUser = beanFactory.getBean("superUser", User.class);
55+
System.out.println(superUser);
56+
57+
// 构造器注入按照类型注入,resolveDependency
58+
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
59+
60+
System.out.println(userHolder);
61+
62+
// 执行 Bean 销毁(容器内)
63+
beanFactory.destroyBean("userHolder", userHolder);
64+
// Bean 销毁并不意味着 Bean 垃圾回收了
65+
System.out.println(userHolder);
66+
67+
// 销毁 BeanFactory 中的单例 Bean
68+
beanFactory.destroySingletons();
69+
// 强制 GC
70+
System.gc();
71+
// 等待一段时间
72+
Thread.sleep(1000L);
73+
// 强制 GC
74+
System.gc();
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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.bean.lifecycle;
18+
19+
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
20+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
21+
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
22+
import org.springframework.core.io.ClassPathResource;
23+
import org.springframework.core.io.Resource;
24+
import org.springframework.core.io.support.EncodedResource;
25+
26+
/**
27+
* Bean 元信息配置示例
28+
*
29+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
30+
* @since
31+
*/
32+
public class BeanMetadataConfigurationDemo {
33+
34+
public static void main(String[] args) {
35+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
36+
// 实例化基于 Properties 资源 BeanDefinitionReader
37+
PropertiesBeanDefinitionReader beanDefinitionReader = new PropertiesBeanDefinitionReader(beanFactory);
38+
String location = "META-INF/user.properties";
39+
// 基于 ClassPath 加载 properties 资源
40+
Resource resource = new ClassPathResource(location);
41+
// 指定字符编码 UTF-8
42+
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
43+
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(encodedResource);
44+
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
45+
// 通过 Bean Id 和类型进行依赖查找
46+
User user = beanFactory.getBean("user", User.class);
47+
System.out.println(user);
48+
}
49+
50+
}

0 commit comments

Comments
 (0)