文章目录
- Spring IOC初始化
- 源码剖析
- 1.prepareRefresh
- 2.obtainFreshBeanFactory
- 3.prepareBeanFactory
- 4.postProcessBeanFactory
- 5.invokeBeanFactoryPostProcessors
- 6.registerBeanPostProcessors
- 7.initMessageSource
- 8.initApplicationEventMulticaster
- 9.onRefresh
- 10.registerListeners
- 11.finishBeanFactoryInitialization
- 11.1createBeanInstance
- 11.2populateBean
- 11.3initializeBean
- 12.finishRefresh
- 13.销毁阶段
Spring IOC初始化
ApplicationContext 是 Spring 的核心接口,表示 Spring 的 IOC 容器,以下三个类是ApplicationContext 接口的常用实现类:ClassPathXmlApplicationContext,AnnotationConfigApplicationContext,FileSystemXmlApplicationContext。
- ClassPathXmlApplicationContext:这个实现类用于从 classpath 中加载 XML 配置文件来初始化 IoC 容器。
- AnnotationConfigApplicationContext:这个实现类用于从 Java 配置类如带有@Configuration 注解的类中加载配置信息来初始化 IoC 容器。
- FileSystemXmlApplicationContext:这个实现类用于从文件系统的指定路径加载 XML 配置文件来初始化 IoC容器。
本文采用第一种方式来初始化IOC容器,首先引入Spring5.3.27版本的依赖,不同版本的实现略有差异,但整体实现逻辑是相同的。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.27</version>
</dependency>
创建一个接口CourseService
@Service
public interface CourseService {
String getCourseName();
}
接口的实现类CourseServiceImpl
public class CourseServiceImpl implements CourseService {
@Override
public String getCourseName() {
return "Spring IOC源码";
}
}
配置文件application.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="courseService" class="com.czl.spring.CourseServiceImpl"/>
</beans>
启动测试类TestSpring
public class TestSpring {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
System.out.println("启动Spring IOC");
CourseService courseService = applicationContext.getBean(CourseService.class);
System.out.println(courseService.getCourseName());
}
}
运行结果
源码剖析
首先从这行代码ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
进行debug,
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
主要执行以下三个方法
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
- super(parent):调用父类的构造方法super(parent),通过创建PathMatchingResourcePatternResolver来设置Bean的资源加载器。
- setConfigLocations(configLocations):将Bean的定义资源文件添加到当前的执行程序中。
//解析配置文件的路径,处理多个资源文件可以用字符串数组
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}
通过源码可以看出,可以使用一个字符串数组来配置多个Spring 的配置文件,比如下面通过字符串数组可以直接配置两个XML配置文件。
String []strXML ={"application.xml","application2.xml"};
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(strXML);
refresh()
:用于初始化和刷新IoC容器,实现bean的注册、实例化和初始化等过程,最终创建出一个完整的Bean对象。
所有的核心方法都在refresh()中实现。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//执行容器刷新前的方法
prepareRefresh();
// 将BeanDefinition注册到DefaultListableBeanFactory的beanDefinitionMap中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为beanFactory设置一些默认的属性和方法
prepareBeanFactory(beanFactory);
try {
// 子类对Bean工厂进行后处理
postProcessBeanFactory(beanFactory);
// 调用注册为Bean的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 解析Bean创建的Bean前后处理器
registerBeanPostProcessors(beanFactory);
// 结束Bean工厂后处理器的处理
beanPostProcess.end();
// 初始化消息源
initMessageSource();
// 初始化事件多播器
initApplicationEventMulticaster();
// 没有具体实现,在上下文子类中可以初始化其他特殊的Bean
onRefresh();
// 检查并注册监听器
registerListeners();
// 实例化所有剩余的非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);
// 发布相应的刷新事件
finishRefresh();
}
// 结束刷新上下文
contextRefresh.end();
}
}
1.prepareRefresh
该方法主要执行容器刷新前的操作。
- 设置容器启动时间:this.startupDate = System.currentTimeMillis();
- 设置关闭状态为false:this.closed.set(false);
- 设置活跃状态为true:this.active.set(true);
- 获取environment对象,并将系统的属性值加到environment对象:getEnvironment().validateRequiredProperties();
- 创建监听器和事件的集合:this.earlyApplicationEvents = new LinkedHashSet<>();
protected void prepareRefresh() {
//...
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2.obtainFreshBeanFactory
该方法主要执行以下两个方法
-
refreshBeanFactory:如果当前已经存在Bean工厂,则先销毁已有的Bean并关闭Bean工厂,再解析application.xml配置文件得到bean的定义信息BeanDefinition注册到DefaultListableBeanFactory 的 beanDefinitionMap 中
-
getBeanFactory:返回 DefaultListableBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
protected final void refreshBeanFactory() throws BeansException {
// 如果当前已经存在Bean工厂,则先销毁已有的Bean并关闭Bean工厂
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建一个新的DefaultListableBeanFactory实例作为Bean工厂
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 设置Bean工厂的序列化ID
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 将Bean定义信息从配置文件加载到Bean工厂中
loadBeanDefinitions(beanFactory);
// 将刚创建的Bean工厂赋值给当前容器的beanFactory属性
this.beanFactory = beanFactory;
}
}
关键方法 loadBeanDefinitions(beanFactory);
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 创建XmlBeanDefinitionReader实例,用于读取XML配置文件的Bean定义
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
// 加载Bean定义
loadBeanDefinitions(beanDefinitionReader);
}
通过loadBeanDefinitions(beanDefinitionReader)去加载beanDefinition
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 获取XML配置文件的数组
Resource[] configResources = getConfigResources();
// 如果数组不为空,则去加载配置文件的Bean定义
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
// 获取XML配置文件的路径
String[] configLocations = getConfigLocations();
// 如果数组不为空,则加载这些配置文件中的Bean定义
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
继续执行loadBeanDefinitions(configResources);
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//加载配置文件的Bean定义
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
// 将XML配置文件封装成doc文档
Document doc = doLoadDocument(inputSource, resource);
// 注册Bean定义,并返回注册的数量
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
}
执行registerBeanDefinitions(doc, resource);
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
//使用documentReader注册Bean的定义信息
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 返回注册的Bean数量
return getRegistry().getBeanDefinitionCount() - countBefore;
}
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
//从XML文档的根节点开始注册Bean定义
doRegisterBeanDefinitions(doc.getDocumentElement());
}
protected void doRegisterBeanDefinitions(Element root) {
//...
// 先对XML文档进行预处理
preProcessXml(root);
// 解析XML中的bean定义
parseBeanDefinitions(root, this.delegate);
// 解析bean之后,对XML进行后置处理
postProcessXml(root);
this.delegate = parent;
}
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//...
// 解析XML中的bean定义
parseDefaultElement(ele, delegate);
}
// 根据不同的标签进行解析,有以下四种标签import、alias、bean、beans,重点关注bean
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 如果元素属于import标签
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
// 处理import的元素
importBeanDefinitionResource(ele);
}
// 如果元素属于alias标签
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
// 处理alias的元素
processAliasRegistration(ele);
}
// 如果元素是bean标签
else if (delegate.nodeName转向ele, BEAN_ELEMENT)) {
// 处理bean元素
processBeanDefinition(ele, delegate);
}
// 如果元素是nested-beans标签
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// 递归处理nested-beans元素
doRegisterBeanDefinitions(ele);
}
}
重点关注bean标签的处理方法processBeanDefinition(ele, delegate);
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析当前元素,得到BeanDefinitionHolder
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
// 如果bdHolder不为空
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 开始注册BeanDefinition实例
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 获取bean定义的名称
String beanName = definitionHolder.getBeanName();
//在注册表中注册bean定义
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 获取bean定义的所有别名
String[] aliases = definitionHolder.getAliases();
// 如果存在别名
if (aliases != null) {
// 遍历所有别名,并在注册表中为每个别名注册对应的bean名称
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
真正注册bean的定义方法registerBeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 断言beanName不为空
Assert.hasText(beanName, "Bean name must not be empty");
// 断言beanDefinition不为空
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
// 获取已存在的bean定义
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
//如果已存在bean定义
if (existingDefinition != null) {
// Spring不允许覆盖bean定义,会抛出BeanDefinitionOverrideException
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 更新bean定义映射信息
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 将beanName和beanDefinition存储到beanDefinitionMap中
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
}
总结:首先获取xml 配置文件的路径,通过 documentLoader 将文件封装成 Doc 格式,再通过BeanDefinitionDocumentReader 来解析 xml 文件,从xml文件的根节点开始遍历,根据不同的标签(import、alias、bean、beans)组装成 beanDefinition,再根据 BeanName 查询 beanDefinition 是否已经注册,如果注册过,则直接抛出异常,如果没有注册,则将 BeanName 作为key, beanDefinition作为value 注册到 DefaultListableBeanFactory 的 beanDefinitionMap 中。
3.prepareBeanFactory
该方法主要为DefaultListableBeanFactory类型的beanFactory设置一些默认的属性和方法。
4.postProcessBeanFactory
该方法没有具体实现,不过子类通过该方法对Bean工厂进行处理。
5.invokeBeanFactoryPostProcessors
该方法可以对 beanFactory 的 BeanDefinition 进行修改。
6.registerBeanPostProcessors
该方法会解析Bean创建的Bean前后处理器,前后处理器会在 Bean 初始化方法前后调用,比如下面的例子
public class ExampleBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 前置处理
System.out.println("bean初始化的前置操作");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 后置处理
System.out.println("bean初始化的后置操作");
return bean;
}
}
执行结果
bean初始化的前置操作
bean初始化
bean初始化的后置操作
另外,AOP的功能也是在这个方法里实现的。
7.initMessageSource
该方法主要初始化信息源,与实现Spring中国际化的功能有关。
8.initApplicationEventMulticaster
该方法主要初始化容器的事件传播器。
9.onRefresh
该方法默认没有具体实现,在子类中可以初始化其他特殊的Bean。
10.registerListeners
该方法主要为事件传播器注册事件监听器,为广播事件服务。
11.finishBeanFactoryInitialization
该方法是IOC容器中最核心的方法,主要实例化所有剩余的非懒加载的单例Bean,包括实例化,属性填充,初始化等操作。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 实例化所有的单例bean
beanFactory.preInstantiateSingletons();
}
public void preInstantiateSingletons(){
// 从beanDefinitions获取所有的beanName集合
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历集合,初始化bean
for (String beanName : beanNames) {
// 通过beanName获取bean
getBean(beanName);
}
}
public Object getBean(String name) throws BeansException {
// 获取bean,依赖注入也是在该方法实现的
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly){
// 根据name得到beanName
String beanName = transformedBeanName(name);
// 检查缓存中是否有单例对象
Object sharedInstance = getSingleton(beanName);
//如果bean是单例的,会解决循环依赖,如果是原型模式,则会直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
if (mbd.isSingleton()) {
// 得到beanName的对应的单例对象
sharedInstance = getSingleton(beanName, () -> {
try {
//创建bean实例
return createBean(beanName, mbd, args);
}
});
}
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
//创建bean实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
// 实例化bean
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
// 填充bean的属性
populateBean(beanName, mbd, instanceWrapper);
// 执行初始化bean的方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
总结:创建bean实例主要有以下步骤,首先遍历beanDefinitionNames得到每一个beanName,根据BeanName到单例缓存中查找是否已经存在实例,如果存在直接返回,如果不存在,则根据beanName的 beanDefinition 生成bean实例, 实例的生成分为三个步骤:
- createBeanInstance 创建实例。
- populateBean 进行属性填充。
- initializeBean 进行初始化操作:先执行 BeanPostProcessor 的前置方法,再执行bean对象的初始化方法,最后执行 BeanPostProcessor 的后置方法。
11.1createBeanInstance
首先是创建实例的方法
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 根据beanName得到Class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 通过无参构造创建实例
return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
// 实例化操作
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 加锁保证线程安全
synchronized (bd.constructorArgumentLock) {
// 得到bean的Class
Class<?> clazz = bd.getBeanClass();
// 通过class得到构造方法
constructorToUse = clazz.getDeclaredConstructor();
// 反射方式创建实例
return BeanUtils.instantiateClass(constructorToUse);
}
}
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) {
// 通过反射的方式创建实例
return ctor.newInstance(argsWithDefaultValues);
}
11.2populateBean
属性填充就是将property标签的value注入给对象的属性name。
<bean id="messageService" class="com.mashibing.hls.MessageServiceImpl">
<property name="example" value="value"/>
</bean>
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 得到BeanDefinition的属性value
PropertyValues pvs = mbd.getPropertyValues();
if (pvs != null) {
// 将value注入给属性name
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs){
// 获取PropertyValue对象数组存储到列表
List<PropertyValue> original = Arrays.asList(pvs.getPropertyValues());
for (PropertyValue pv : original) {
// 获取属性的name
String propertyName = pv.getName();
// 获取value
Object originalValue = pv.getValue();
// 设置属性值
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
}
public void setPropertyValues(PropertyValues pvs){
setPropertyValues(pvs, false, false);
}
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid){
// 通过反射的方式进行赋值
setPropertyValue(pv);
}
11.3initializeBean
初始化的过程就是在执行 BeanPostProcessor 的前后置方法过程中穿插执行init方法。
// 初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//调用postProcessBeforeInitialization方法,返回原始Bean包装器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
// 调用postProcessAfterInitialization方法,再返回Bean包装器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
//返回包装后的Bean
return wrappedBean;
}
// 执行BeanPostProcessors接口下的类
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName){
Object result = existingBean;
//遍历BeanPostProcessors列表
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 返回给定的Bean
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 如果 current为null
if (current == null) {
//直接返回result
return result;
}
result = current;
}
//返回经过后置处理后的result
return result;
}
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd){
// 如果mbd不为空且bean不是NullBean
if (mbd != null && bean.getClass() != NullBean.class) {
// 获取初始化方法名
String initMethodName = mbd.getInitMethodName();
// 调用自定义的init方法
invokeCustomInitMethod(beanName, bean, mbd);
// 反射执行方法
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
methodToInvoke.invoke(bean);
}
}
// 执行所有的BeanPostProcessors接口下的类
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName){
//初始化结果对象为result,默认引用existingBean
Object result = existingBean;
//遍历BeanPostProcessors列表
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//postProcessAfterInitialization对bean实例进行包装
Object current = processor.postProcessAfterInitialization(result, beanName);
// 如果current为null
if (current == null) {
//直接返回result
return result;
}
result = current;
}
//返回包装后的result
return result;
}
12.finishRefresh
到这所有的对象已经创建完成,容器已经完成启动,该方法会发布容器的生命周期事件。
13.销毁阶段
创建完对象就可以正常使用,使用完成后就进入销毁阶段,Spring会调用close方法销毁
public void close() {
synchronized (this.startupShutdownMonitor) {
//销毁bean
doClose();
}
}
protected void doClose() {
// 清空BeanFactory的缓存
destroyBeans();
// 再将beanFactory置为null
closeBeanFactory();
}
protected void destroyBeans() {
// 清除beanName与Bean包含的Bean名称集的映射集合
this.containedBeanMap.clear();
// 清除beanName与一组相关的Bean名称的映射集合
this.dependentBeanMap.clear();
// 清除beanName与bean依赖项的映射集合
this.dependenciesForBeanMap.clear();
// 清除注册表中所有的单例实例
clearSingletonCache();
}
protected void clearSingletonCache() {
// 使用singletonObjects对象进行同步,确保只有一个线程可以执行清除方法
synchronized (this.singletonObjects) {
// 清空singletonObjects集合,该集合存储了所有的单例Bean实例
this.singletonObjects.clear();
// 清空singletonFactories集合,该集合存储了所有的单例Bean工厂
this.singletonFactories.clear();
// 清空earlySingletonObjects集合,该集合存储了早期暴露的单例Bean实例
this.earlySingletonObjects.clear();
// 清空registeredSingletons集合,该集合存储了所有已注册的单例Bean名称
this.registeredSingletons.clear();
// 将标志设置为false,表示当前没有单例Bean正在销毁
this.singletonsCurrentlyInDestruction = false;
}
}
private void clearByTypeCache() {
// 清空按类型缓存的Bean名称集合
this.allBeanNamesByType.clear();
// 清空按类型缓存的单例Bean名称的集合
this.singletonBeanNamesByType.clear();
}
protected final void closeBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory != null) {
beanFactory.setSerializationId(null);
// 将beanFactory设置为空
this.beanFactory = null;
}
}
另外可以在配置文件中自定义初始化 init 和销毁 destory 的方法
public class CourseServiceImpl implements CourseService {
@Override
public String getCourseName() {
return "Spring IOC源码";
}
public void init(){
System.out.println("类的初始化阶段");
}
public void destroy(){
System.out.println("类的销毁阶段");
}
}
然后在配置文件添加对应的标签即可。
<bean id="courseService" class="com.czl.spring.CourseServiceImpl" init-method="init" destroy-method="destroy"/>