Spring源码二IOC容器源码

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();
		}
	}
  1. super(parent):调用父类的构造方法super(parent),通过创建PathMatchingResourcePatternResolver来设置Bean的资源加载器。
  2. 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);
  1. 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实例, 实例的生成分为三个步骤:

  1. createBeanInstance 创建实例。
  2. populateBean 进行属性填充。
  3. 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"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值