01 实例化Spring Bean
常规
- 构造器(xml,java注解 Java API)
- 静态工厂方法(xml java api)
- 通过Bean工厂方法(xml java api)
- 通过FactoryBean(xml,java注解 Java API)
1
2
3
4
5
6
7
8
9
10
11
12
13
14<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 静态方法实例化 Bean -->
<bean id="user-by-static-method" class="org.geekbang.thinking.in.spring.ioc.overview.domain.User"
factory-method="createUser"/>
<!-- 实例(Bean)方法实例化 Bean -->
<bean id="user-by-instance-method" factory-bean="userFactory" factory-method="createUser"/>
<bean id="userFactory" class="org.geekbang.thinking.in.spring.bean.factory.DefaultUserFactory"/>
<!-- FactoryBean实例化 Bean -->
<bean id="user-by-factory-bean" class="org.geekbang.thinking.in.spring.bean.factory.UserFactoryBean" />
</beans>特殊
- ServiceLoaderFactoryBean(xml,java注解 Java API)
- AutowireCapableBeanFactory#createBean(class,int,boolean)
- BeanDefinitionRegistry#registerBeanDefinitoin(string,BeanDefiniton)这里涉及到关于ServiceLoader的使用方法,想想mysql的驱动jar包是怎么被读取到项目中的,mysql定义了一系列的接口,各个厂商实现的不同的驱动都是通过ServiceLoader方式来读取的。
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
28public class SpecialBeanInstantiationDemo {
public static void main(String[] args) {
// 配置 XML 配置文件
// 启动 Spring 应用上下文
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/special-bean-instantiation-context.xml");
// 通过 ApplicationContext 获取 AutowireCapableBeanFactory
AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
ServiceLoader<UserFactory> serviceLoader = beanFactory.getBean("userFactoryServiceLoader", ServiceLoader.class);
displayServiceLoader(serviceLoader);
demoServiceLoader();
// 创建 UserFactory 对象,通过 AutowireCapableBeanFactory
UserFactory userFactory = beanFactory.createBean(DefaultUserFactory.class);
System.out.println(userFactory.createUser());
}
public static void demoServiceLoader() {
ServiceLoader<UserFactory> serviceLoader = load(UserFactory.class, Thread.currentThread().getContextClassLoader());
displayServiceLoader(serviceLoader);
}
private static void displayServiceLoader(ServiceLoader<UserFactory> serviceLoader) {
Iterator<UserFactory> iterator = serviceLoader.iterator();
while (iterator.hasNext()) {
UserFactory userFactory = iterator.next();
System.out.println(userFactory.createUser());
}
}
}02 初始化Spring Bean
- @PostConstruct
- 实现InitializingBean接口的afterPropertiesSet()方法
- 自定义初始化方法
- xml<bean init-method=”init” ../>
- Java注解 @Bean(initMethod=”init”)
- Java API AbstractBeanDefinition#setInitMethodName(string)测试类
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
36public class DefaultUserFactory implements UserFactory, InitializingBean, DisposableBean {
// 1. 基于 @PostConstruct 注解
public void init() {
System.out.println("@PostConstruct : UserFactory 初始化中...");
}
public void initUserFactory() {
System.out.println("自定义初始化方法 initUserFactory() : UserFactory 初始化中...");
}
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean#afterPropertiesSet() : UserFactory 初始化中...");
}
public void preDestroy() {
System.out.println("@PreDestroy : UserFactory 销毁中...");
}
public void destroy() throws Exception {
System.out.println("DisposableBean#destroy() : UserFactory 销毁中...");
}
public void doDestroy() {
System.out.println("自定义销毁方法 doDestroy() : UserFactory 销毁中...");
}
public void finalize() throws Throwable {
System.out.println("当前 DefaultUserFactory 对象正在被垃圾回收...");
}
}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// Configuration Class
public class BeanInitializationDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 Configuration Class(配置类)
applicationContext.register(BeanInitializationDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 非延迟初始化在 Spring 应用上下文启动完成后,被初始化
System.out.println("Spring 应用上下文已启动...");
// 依赖查找 UserFactory
UserFactory userFactory = applicationContext.getBean(UserFactory.class);
System.out.println(userFactory);
System.out.println("Spring 应用上下文准备关闭...");
// 关闭 Spring 应用上下文
applicationContext.close();
System.out.println("Spring 应用上下文已关闭...");
}
public UserFactory userFactory() {
return new DefaultUserFactory();
}
}03 延迟初始化Spring Bean
- XML
- Java注解 @Lazy(true)
- spring容器返回的bean和延迟初始化的bean有什么区别?
- @PreDestory
1
2
3
4
5
6
7org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#CommonAnnotationBeanPostProcessor
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
} - 实现DisposableBean接口的destory()方法
1
2
3
4String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
} - 自定义销毁方法
- xml<bean destory=”destory” .. />
- Java注解 @Bean(destory=”destory”)
- Java API AbstractBeanDefinition#setDestoryMethodName(string)
- 三者执行顺序 1-2-3
- 关闭spring容器
- 执行GC
- spring bean覆盖 finalize()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class BeanGarbageCollectionDemo {
public static void main(String[] args) throws InterruptedException {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 Configuration Class(配置类)
applicationContext.register(BeanInitializationDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 关闭 Spring 应用上下文
applicationContext.close();
Thread.sleep(5000L);
// 强制触发 GC
System.gc();
Thread.sleep(5000L);
}
}06将外部单体对象注入到IOC中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class SingletonBeanRegistrationDemo {
public static void main(String[] args) throws InterruptedException {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 创建一个外部 UserFactory 对象
UserFactory userFactory = new DefaultUserFactory();
SingletonBeanRegistry singletonBeanRegistry = applicationContext.getBeanFactory();
// 注册外部单例对象
singletonBeanRegistry.registerSingleton("userFactory", userFactory);
// 启动 Spring 应用上下文
applicationContext.refresh();
// 通过依赖查找的方式来获取 UserFactory
UserFactory userFactoryByLookup = applicationContext.getBean("userFactory", UserFactory.class);
System.out.println("userFactory == userFactoryByLookup : " + (userFactory == userFactoryByLookup));
// 关闭 Spring 应用上下文
applicationContext.close();
}
}