概念
IOC:Inversion of comtrol 控制反转,这个概念说起来很熟悉,理解起来还是有点困难的。要先弄清楚第一个问题:谁控制了谁?
public class Persion {
private Order order;
public Persion(Order order) {
this.order = order;
}
}
Persion 持有Order 的引用,在创建Persion的时候一定要有Order的对象传入才可以,这就是Order 控制着Persion.
现在要将这个控制权交给Persion,怎么做到的呢?IOC来管理所有的对象,Persion需要什么跟IOC要就可以,怎么要呢,通过依赖注入来要。
DI:Dependecy inversion 依赖注入,IOC是更加抽象的一层含义,可以只理解成一种思想,通过容器来控制对象的思想,真是的实现手段就是DI;
DI的三种实现方式:
接口注入:对代码有入侵不推荐
注解注入:@Autowired根据类型注入 @Resource 根据名称注入
setter注入:通过setter方法注入
容器启动流程
这个流程只是一个大概的流程方便我们更好的理解IOC
重要类的源码解析
AbstractApplicationContext的refresh()定义了整个spring启动的流程,有关bean的几个重要的步骤做了解释。
跟踪 obtainFreshBeanFactory()
AbstractRefreshableApplicationContext
loadBeanDefinitions()这个方法中做的事情
如果是读取XML文件中的bean就会用到XmlBeanDefinitionReader 将xml文件的内容解析成BeanDefinition
如果是扫描注解创建bean 就会用到AnnotatedBeanDefinitionReader将扫描到的class文件 通过类的加载器加载到容器种转化成BeanDefinition
最后BeanDefinition保存在
接下来我们分析一下这个方法
this.finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//先初始化ConversionService类型的bean ConversionService这个是前端向controller传递参数的时候需要特殊处理的时候用的
//例如时间字符串 勇敢date接受
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
//初始化LoadTimeWeaverAware类型的bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
// 预初始化 继续跟踪这个方法
beanFactory.preInstantiateSingletons();
}
DefaultListableBeanFactory
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
// 循环遍历所有非懒加载的beanDefinition
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
//如果已初始化完成这一步就可以直接获取到
Object singletonInstance = this.getSingleton(beanName);
// 如果是这个SmartInitializingSingleton类型的就在这里回调
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
// 如果是FactoryBean在beanName 前加 &
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
这个方法中我们可以看到在初始化bean的时候factoryBean是要特殊处理的跟普通的Bean不一样。简单的Bean会通过getBean这个方法初始化,继续看这个方法
AbstractBeanFactory
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
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;
}
}
到这里总的来说我们就分析完了,下面再总结一下
BeanFactory FactoryBean ApplicationContext
BeanFactory :是spring 框架的根基,是面向spring研发人员的,他的getBean发放是懒加载
功能:1.提供IOC的配置机制。
2. 包含bean的各种定义,便于实例化Bean
3. 建立bean之间的各种依赖关系
4. bean生命周期的管理
FactoryBean:是一个特殊的Bean,(在初始化的时候与普通的bean不一样),内部构造复杂的Bean,是一个工厂bean.
ApplicationContext :是面向spring使用者的。继承多个接口的高级容器,大多数功能的实现依赖的是DefaultListableBeanFactory这个类。
Bean的生命周期:
如果不是由spring;来管理的话我们的对象new->destory很简单.但是由spring来管理bean以后,bean的创建过程就比较复杂了,生命周期其实就是创建和销毁的过程.
- 从XML或者@中扫描到对象,通过BeanDefinitionReader读取bean的信息,加载,注册beanDefinition
- 注入Aware的依赖 实现这几个接口 BeanNameAware, BeanFactoryAware,
ApplicationContextAware, - 实现接口InitializingBean重写方法afterPropertiesSet()
- 执行通用的前置方法. 实现BeanPostProcessor接口的postProcessBeforeInitialization()方法.
- 通过注解执行init方法@Bean(initMethod = “init”),通过注解构造方法之后执行@PostConstruct
- 执行方法BeanPostProcessor.postProcessorAfterInitialization()
- 对象创建完毕
对象的销毁 - 执行 DisposableBean.destory() 方法
- 执行自定义的destory方法或者 @PreDestory 标注的方法;
- 对象销毁完毕
这些过程大家都可以手动试一下,验证一下的
public class MessageServiceImpl implements MessageService, BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor {
public void say() {
System.out.println("hello");
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("MessageServiceImpl setBeanFactory");
}
public void setBeanName(String s) {
System.out.println("MessageServiceImpl setBeanName"+s);
}
public void destroy() throws Exception {
System.out.println("MessageServiceImpl destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("MessageServiceImpl afterPropertiesSet");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("MessageServiceImpl setApplicationContext");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("postProcessBeanFactory====");
}
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessBeforeInitialization");
return null;
}
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("postProcessAfterInitialization");
return null;
}
}