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 上是有先后顺序的:
初始化方法
@PostConstructInitializingBean 中的 afterPropertiesSet()@Bean 中指定 init()销毁方法
@PreDestroyDisposableBean 中的 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