1.IOC原理
IOC(Inversion of Control):控制反转
- Spring Core最核心的部分
- 需要先了解依赖注入(Dependency Inversion)
类别之间存在依赖,被依赖类的修改将引起对依赖类的修改
轮胎类构造函数的修改会引起所有上层类的修改:
- Setter:实现特定属性的public setter方法,来让IOC容器注入所依赖类型的对象
- Interface:实现特定接口,来让IOC容器注入所依赖类型的对象
- Constructor:实现特定参数的构造函数,来让IOC容器注入所依赖类型的对象
- Annotation:通过java的注解机制来让IOC容器注入所依赖类型的对象
依赖倒置原则:高层模块不应该依赖低层模块 ,两者都应该依赖其抽象
从上层往下查找依赖关系,到达最底层后再往上一步一步的new
2.Spring IOC的应用
Spring IOC的两个表示容器的核心接口
-
BeanFactory
-
ApplicationContext
3.Spring IOC的refresh源码
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException var3) {
;
}
}
}
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext)applicationContext).refresh();
}
完成配置类的解析 ,注册,初始化,web内置容器的构造等等
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
//获取BeanFactory实例
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//对BeanFactory进行相关设置
this.prepareBeanFactory(beanFactory);
try {
//设置spring容器启动时间,撤销关闭状态,开启活跃状态;初始化属性元信息;验证环境信息
this.postProcessBeanFactory(beanFactory);
//调用工厂后处理器,处理各类bean标签,扫描bean文件,解析成一个个的bean
this.invokeBeanFactoryPostProcessors(beanFactory);
//从spring容器中找出实现BeanPostProcessors的bean,并设置到BeanFactory的属性中,之后bean被实例化时,会调用BeanPostProcessor
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
//初始化bean的事件广播器(用于事件的发布)
this.initApplicationEventMulticaster();
//
this.onRefresh();
//注册事件监听器
this.registerListeners();
//实例化beanFactory中已经注册但还没被实例化的各种bean
this.finishBeanFactoryInitialization(beanFactory);
//
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
4.Spring IOC的getBean方法的解析
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//提取bean的名字
String beanName = this.transformedBeanName(name);
//获取bean或工场的实例
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
//将父类的一些属性合并到子类中
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
//如果存在依赖,需要递归的去实例化依赖类
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}