Bean
的生命周期就是Bean
的创建
-初始化
-销毁
过程
Spring IoC 容器
管理一个或多个 Bean
。这些 Bean
通过我们定义的配置信息进行创建。在容器内部,这些 Bean
定义表示为 BeanDefinition
对象,它包含了以下元数据:
package-qualified
类名:通常是被定义 Bean
的实际实现类Bean
行为配置元素,规定了 Bean
在容器中的行为(scope
、生命周期回调
等)Bean
执行其工作所需要的其他 Bean
的引用。这些引用也称为 依赖
pool
的大小限制,或者在管理连接池的 Bean
中使用的连接数public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
...
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
void setScope(@Nullable String scope);
@Nullable
String getScope();
...
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
void setPrimary(boolean primary);
boolean isPrimary();
void setFactoryBeanName(@Nullable String factoryBeanName);
/**
* Return the factory bean name, if any.
*/
@Nullable
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
...
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
...
boolean isSingleton();
/**
* Return whether this a Prototype, with an independent instance
* returned for each call.
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();
/**
* Return whether this bean is "abstract", that is, not meant to be instantiated.
*/
boolean isAbstract();
...
}
构造器
实例化当使用构造器实例化 Bean
时,只需要普通类的默认(无参)构造器即可。
public class Car {
public Car() {
System.out.println("car constructor...");
}
}
@Bean
public Car car() {
return new Car();
}
// 初始化 IoC 容器会输出
car constructor...
静态工厂方法
实例化public class ClientService {
private static ClientService clientService = new ClientService();
public ClientService() {
System.out.println("init by constructor...");
}
public static ClientService createInstance() {
return clientService;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="clientService"
class="com.keke.bean.ClientService"
factory-method="createInstance"/>
beans>
// 初始化 IoC 容器会输出
init by constructor...
实例工厂方法
实例化与使用 静态工厂方法
进行实例化相比,使用 实例工厂方法
进行的实例化从容器中调用现有 Bean
的非静态方法来创建 Bean
。要使用这种方法,需要将 class
属性保留为空,并在 factory-bean
属性中指定包含用于创建对象的实例方法的当前(或父或祖先)容器中的 Bean
名称。使用 factory-method
属性设置工厂方法本身的名称。举例如下:
// 首先定义一个接口
public interface ClientService {}
// 定义两个实现类
public class ClientServiceImpl implements ClientService {}
public class AccountServiceImpl implements ClientService {}
定义一个类作为 factory bean
并加入到 IoC 容器
中,用于通过实例或静态工厂方法创建对象:
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
private static ClientService accountService = new AccountServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
public ClientService createAccountServiceInstance() {
return accountService;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="serviceLocator" class="com.keke.bean.DefaultServiceLocator">
// 这里可以进行依赖注入
bean>
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
<bean id="accountService"
factory-bean="serviceLocator"
factory-method="createAccountServiceInstance"/>
beans>
Bean
的生命周期(初始化和销毁方法)从 Spring 官方文档 中我们了解到,在 Spring 2.5
开始,我们有三种方式指定 Bean
的生命周期:
@Bean
注解指定初始化和销毁方法public class Car {
public void init() {
System.out.println("car init...");
}
public void destory() {
System.out.println("car destory...");
}
}
@Bean(initMethod = "init", destroyMethod = "destory")
public Car car() {
return new Car();
}
InitializingBean
和 DisposableBean
接口@Component
public class Cat implements InitializingBean, DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("cat destroy...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("cat afterPropertiesSet...");
}
}
@PostConstruct
和 @PreDestory
@Component
public class Dog {
@PostConstruct
public void init() {
System.out.println("dog init");
}
@PreDestroy
public void destroy() {
System.out.println("dog destroy");
}
}
除了
初始化
和销毁
回调,由Spring
管理的对象还可以实现Lifecycle
接口,以便这些对象可以参与启动和关闭过程,这是由容器自己的生命周期驱动的。
以上三种指定 Bean
生命周期的方式作用于同一个 Bean
上是有先后顺序的:
初始化方法
@PostConstruct
InitializingBean
中的 afterPropertiesSet()
@Bean
中指定 init()
销毁方法
@PreDestroy
DisposableBean
中的 destory()
@Bean
中指定 destroy()
验证代码如下:
public class Car implements InitializingBean, DisposableBean {
public void init() {
System.out.println("car init by @Bean");
}
public void destory() {
System.out.println("car destroy by @Bean");
}
@Override
public void destroy() throws Exception {
System.out.println("car destroy by DisposableBean");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("car init by InitializingBean");
}
@PostConstruct
public void initi() {
System.out.println("car init by @PostConstruct");
}
@PreDestroy
public void destroyi() {
System.out.println("car destroy by @PreDestroy");
}
}
初始化 IoC 容器
后关闭容器,结果输出:
car init by @PostConstruct
car init by InitializingBean
car init by @Bean
car destroy by @PreDestroy
car destroy by DisposableBean
car destroy by @Bean