Skip to content

Commit

Permalink
Merge pull request mercyblitz#1 from mercyblitz/master
Browse files Browse the repository at this point in the history
Chapter 10
  • Loading branch information
geektime-geekbang authored Jan 9, 2020
2 parents 4a02523 + ed73d6b commit 351488d
Show file tree
Hide file tree
Showing 60 changed files with 3,258 additions and 6 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ license-list
# grpc compiler
compiler/gradle.properties
compiler/build/*
compiler/.gradle/*
compiler/.gradle/*


# Tomcat
.extract
27 changes: 27 additions & 0 deletions thinking-in-spring/bean-lifecycle/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>thinking-in-spring</artifactId>
<groupId>org.geekbang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>

<groupId>org.example</groupId>
<artifactId>bean-lifecycle</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>

<dependency>
<groupId>org.geekbang</groupId>
<artifactId>ioc-container-overview</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.geekbang.thinking.in.spring.bean.lifecycle;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;

/**
* 注解 BeanDefinition 解析示例
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @since
*/
public class AnnotatedBeanDefinitionParsingDemo {

public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 基于 Java 注解的 AnnotatedBeanDefinitionReader 的实现
AnnotatedBeanDefinitionReader beanDefinitionReader = new AnnotatedBeanDefinitionReader(beanFactory);
int beanDefinitionCountBefore = beanFactory.getBeanDefinitionCount();
// 注册当前类(非 @Component class)
beanDefinitionReader.register(AnnotatedBeanDefinitionParsingDemo.class);
int beanDefinitionCountAfter = beanFactory.getBeanDefinitionCount();
int beanDefinitionCount = beanDefinitionCountAfter - beanDefinitionCountBefore;
System.out.println("已加载 BeanDefinition 数量:" + beanDefinitionCount);
// 普通的 Class 作为 Component 注册到 Spring IoC 容器后,通常 Bean 名称为 annotatedBeanDefinitionParsingDemo
// Bean 名称生成来自于 BeanNameGenerator,注解实现 AnnotationBeanNameGenerator
AnnotatedBeanDefinitionParsingDemo demo = beanFactory.getBean("annotatedBeanDefinitionParsingDemo",
AnnotatedBeanDefinitionParsingDemo.class);
System.out.println(demo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.geekbang.thinking.in.spring.bean.lifecycle;

import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* Bean 初始化生命周期示例
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @since
*/
public class BeanInitializationLifecycleDemo {

public static void main(String[] args) {

executeBeanFactory();

}

private static void executeBeanFactory() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
// 添加 CommonAnnotationBeanPostProcessor 解决 @PostConstruct
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
// 显示地执行 preInstantiateSingletons()
// SmartInitializingSingleton 通常在 Spring ApplicationContext 场景使用
// preInstantiateSingletons 将已注册的 BeanDefinition 初始化成 Spring Bean
beanFactory.preInstantiateSingletons();

// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);

User superUser = beanFactory.getBean("superUser", User.class);
System.out.println(superUser);

// 构造器注入按照类型注入,resolveDependency
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);

System.out.println(userHolder);

}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.geekbang.thinking.in.spring.bean.lifecycle;

import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* Bean 实例化生命周期示例
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @since
*/
public class BeanInstantiationLifecycleDemo {

public static void main(String[] args) {
executeBeanFactory();

System.out.println("--------------------------------");

executeApplicationContext();
}

private static void executeBeanFactory() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
// beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
// 方法二:将 MyInstantiationAwareBeanPostProcessor 作为 Bean 注册
// 基于 XML 资源 BeanDefinitionReader 实现
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);

User superUser = beanFactory.getBean("superUser", User.class);
System.out.println(superUser);

// 构造器注入按照类型注入,resolveDependency
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);
}

private static void executeApplicationContext() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
applicationContext.setConfigLocations(locations);
// 启动应用上下文
applicationContext.refresh();

User user = applicationContext.getBean("user", User.class);
System.out.println(user);

User superUser = applicationContext.getBean("superUser", User.class);
System.out.println(superUser);

// 构造器注入按照类型注入,resolveDependency
UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);
System.out.println(userHolder);

// 关闭应用上下文
applicationContext.close();

}


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.geekbang.thinking.in.spring.bean.lifecycle;

import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;

/**
* TODO
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @since
*/
public class BeanLifecycleDemo {

public static void main(String[] args) throws InterruptedException {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
// 添加 MyDestructionAwareBeanPostProcessor 执行销毁前回调
beanFactory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
// 添加 CommonAnnotationBeanPostProcessor 解决 @PostConstruct @PreDestroy
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());

XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
// 显示地执行 preInstantiateSingletons()
// SmartInitializingSingleton 通常在 Spring ApplicationContext 场景使用
// preInstantiateSingletons 将已注册的 BeanDefinition 初始化成 Spring Bean
beanFactory.preInstantiateSingletons();

// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);

User superUser = beanFactory.getBean("superUser", User.class);
System.out.println(superUser);

// 构造器注入按照类型注入,resolveDependency
UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);

System.out.println(userHolder);

// 执行 Bean 销毁(容器内)
beanFactory.destroyBean("userHolder", userHolder);
// Bean 销毁并不意味着 Bean 垃圾回收了
System.out.println(userHolder);

// 销毁 BeanFactory 中的单例 Bean
beanFactory.destroySingletons();
// 强制 GC
System.gc();
// 等待一段时间
Thread.sleep(1000L);
// 强制 GC
System.gc();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.geekbang.thinking.in.spring.bean.lifecycle;

import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;

/**
* Bean 元信息配置示例
*
* @author <a href="mailto:[email protected]">Mercy</a>
* @since
*/
public class BeanMetadataConfigurationDemo {

public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 实例化基于 Properties 资源 BeanDefinitionReader
PropertiesBeanDefinitionReader beanDefinitionReader = new PropertiesBeanDefinitionReader(beanFactory);
String location = "META-INF/user.properties";
// 基于 ClassPath 加载 properties 资源
Resource resource = new ClassPathResource(location);
// 指定字符编码 UTF-8
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(encodedResource);
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}

}
Loading

0 comments on commit 351488d

Please sign in to comment.