IoC 全称为 Inversion of Control(控制反转),由 Spring IOC 容器来负责对象的生命周期和对象之间的关系
主要依赖源码是 spring-beans 和 spring-context 两个包
构造器注入:
被注入的对象通过在其构造方法中声明依赖对象的参数列表,让外部知道它需要哪些依赖对象。
YoungMan(BeautifulGirl beautifulGirl){
this.beautifulGirl = beautifulGirl;
}
构造器注入方式比较直观,对象构造完毕后就可以直接使用。
setter 方法注入:
对于 JavaBean 对象而言,我们一般都是通过 getter 和 setter 方法来访问和设置对象的属性。
public class YoungMan {
private BeautifulGirl beautifulGirl;
public void setBeautifulGirl(BeautifulGirl beautifulGirl) {
this.beautifulGirl = beautifulGirl;
}
}
接口方式注入:
接口方式注入显得比较霸道,因为它需要被依赖的对象实现不必要的接口,带有侵入性。一般都不推荐这种方式。
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
FileSystemXmlApplicationContext 的构造函数需要一个 xml 配置文件在系统中的路径,其他和 ClassPathXmlApplicationContext 基本上一样。
AnnotationConfigApplicationContext 是基于注解来使用的,它不需要配置文件,采用 java 配置类和各种注解来配置。
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
//如果已经有 ApplicationContext,并需要配置成父子关系
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
Assert.notNull(paths, "Path array must not be null");
Assert.notNull(clazz, "Class argument must not be null");
this.configResources = new Resource[paths.length];
for(int i = 0; i < paths.length; ++i) {
this.configResources[i] = new ClassPathResource(paths[i], clazz);
}
this.refresh(); //核心方法
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
/**
* 初始化容器
*/
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符。
this.prepareRefresh();
/**
* 配置文件解析成一个个 Bean 定义,注册到 BeanFactory 中。
* Bean还没有初始化,只是配置信息都提取出来了。
*/
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//设置 BeanFactory 的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的bean
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
//初始化当前 ApplicationContext 的 MessageSource,国际化
this.initMessageSource();
this.initApplicationEventMulticaster();
//典型的模板方法(钩子方法),
//具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
this.onRefresh();
this.registerListeners();
//初始化所有的 singleton beans(lazy-init 的除外)
this.finishBeanFactoryInitialization(beanFactory);
//最后,广播事件,ApplicationContext初始化完成
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
//销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源。
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
/**
* 创建 Bean 容器前的准备工作
*/
protected void prepareRefresh() {
//记录启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (this.logger.isDebugEnabled()) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Refreshing " + this);
} else {
this.logger.debug("Refreshing " + this.getDisplayName());
}
}
this.initPropertySources();
this.getEnvironment().validateRequiredProperties(); //校验 xml 配置文件
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet();
}
/**
* 创建 Bean 容器,加载并注册 Bean,这里将会初始化 BeanFactory、加载 Bean、注册 Bean,Bean 并没有完成初始化
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory(); //关闭旧的 BeanFactory,创建新的 BeanFactory
return this.getBeanFactory(); //返回刚刚创建的 BeanFactory
}
/**
* 创建 Bean 容器,加载并注册 Bean,这里将会初始化 BeanFactory、加载 Bean、注册 Bean,Bean 并没有完成初始化
*/
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans(); //如果 ApplicationContext 中已经加载过 BeanFactory,销毁所有 Bean
this.closeBeanFactory(); //关闭 BeanFactory
}
try {
DefaultListableBeanFactory beanFactory = this.createBeanFactory(); //初始化BeanFactory实现类
beanFactory.setSerializationId(this.getId()); //序列化
this.customizeBeanFactory(beanFactory); //设置 BeanFactory 的两个配置属性:是否允许 BeanDefinition 覆盖、是否允许循环引用
//BeanDefinition 中保存了 Bean 信息
//比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean
//初始化 Bean 容器:配置文件的配置信息转换为一个个 BeanDefinition,然后注册各个 BeanDefinition 到 BeanFactory。
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
}
原文:https://www.cnblogs.com/loveer/p/11566625.html