一、生命周期
1.boot项目启动扫描文件获取全部class
2.beanDefinition
这个主要是判断bean类型scope(单例还是原型)是否是懒加载islazy,beanClass是否有改动等。
懒加载:使用时才创建
beanClass如何操作:
实现BeanFactoryPostProcessor接口
在这里可以对Mapper之类的bean进行配置 ,比如用代理对象的方法,去返回该类。然后再通过registSinglonBean()的方法使自动注解里面有值。还有像在FactoryBean,或者直接使用@Bean都是可以的。
FactoryBean:是一个接口。有三个方法。除了issingleton()那个方法是默认方法判断是否是单例可以不用改,另外两个都是可以操作的
@Bean:这个就是和boot配置一样的,哪里都可以写。只是写在配置文件里比较规范而已= =
3.实例化
P.S.mapper这样的不是spring组建的是通过mybits组建的,想想以前初学时候的操作。
之所以提到这个是因为beanFactory里面有creatBean()和registBean()方法。creatBean是需要spring去组装,而后者的话是你自己设置新建进单例池,spring是不会管你的。就像mapper那样。
4.beanPostProcessor
这个在BeanFactory组建后就可以使用了。BeanFactory是在扫描全项目文件的时候就组建了。
5.填充属性
6.判断对象是否有使用BeanNameAware。
源码如下图这个方法是在接口中
7.判断该对象有没有实现InitializingBean接口
还是在同一个类中,代码判断
8.单例池 Map<beanName,对象>
9.处理AOP
89看前面文章
二、如果是从getBean()这个方法开始
点进方法来到
流程:BeanFactory.getBean()->AbstractBeanFactory.getBean()->AbstractBeanFactory.doGetBean()
最后操作是到doGetBean()封装的。
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
/**从三级缓存中获取 ,这个是spring 打断循环依赖的处理办法
* 使用三级缓存的原因是因为spring创建bean对象的时候流程是:
* 放入工厂缓存(第三级-》实例化-》属性赋值(第二级-》初始化-》AOP增强
* 如果使用二级缓存数据是残缺的(可能没有属性赋值或者强化
* 三级缓存就是ObjectFactory从这里拿的数据才是最完整的,已经被处理过的。
* 二级缓存是后置处理器那边处理的,会有设置的属性,AOP增强以后,会将对象
* 放入一级缓存(成品对象),删除三级缓存的数据(初始对象)。
*
* 循环依赖是指:自身依赖于自身,互相循环依赖,多组循环依赖。
* 依赖说穿了就是A的创建完成会依赖于B的创建,B的创建也会依赖于A的创建。
* 如果没办法互相解耦,那么对象就将创建失败。直接报错。
*
*/
Object sharedInstance = this.getSingleton(beanName);
Object beanInstance;
//如果缓存里有就直接返回
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 + "'");
}
}
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition) null);
} else {
// 循环依赖有三种,setter注入、多实例和构造函数,Spring 只能解决 setter 注入,所以这里是 Prototype(原型:直接使用copy的) 则会抛出异常
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//从父工厂获取
BeanFactory parentBeanFactory = this.getParentBeanFactory();
//如果有这个对象,并且这个对象不属于BeanDefinition
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
//这个方法是判断beanName是否是从alias(别名)配置中有的。"&"关键字
String nameToLookup = this.originalBeanName(name);
//从工厂里拿
if (parentBeanFactory instanceof org.springframework.beans.factory.support.AbstractBeanFactory) {
return ((org.springframework.beans.factory.support.AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
//如果参数存在,那么调用其他工厂的接口。getBean()是抽象的
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);
}
//在spring里面创建对象
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
try {
if (requiredType != null) {
//进行标记
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
//检查对象是否抽象的
this.checkMergedBeanDefinition(mbd, beanName, args);
//检查是否有循环依赖
String[] dependsOn = mbd.getDependsOn();
String[] var12;
if (dependsOn != null) {
var12 = dependsOn;
int var13 = dependsOn.length;
for (int var14 = 0; var14 < var13; ++var14) {
String dep = var12[var14];
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 var31) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var31);
}
}
}
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var12 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
beanInstance = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ��" + beanName + "'");
}
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;
});
beanInstance = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var30) {
throw new ScopeNotActiveException(beanName, scopeName, var30);
}
}
} catch (BeansException var32) {
beanCreation.tag("exception", var32.getClass().toString());
beanCreation.tag("message", String.valueOf(var32.getMessage()));
this.cleanupAfterBeanCreationFailure(beanName);
throw var32;
} finally {
beanCreation.end();
}
}
return this.adaptBeanInstance(name, beanInstance, requiredType);
}
三、部分类的不同
1.BeanFactory和FactoryBean的区别
BeanFactory是一个大类,啥类都在往里面加,是个对象,一个接口
FactoryBean是一个小类,就是一个bean
2.BeanFactory和ApplicationContext的区别
ApplicationContext是一个BeanFactory的一个子接口,它有着更丰富的内容,功能强大
BeanFactory功能专一
四、实现
4.1 最简版
根据spring的逻辑,我们可知首先你要有个装Bean池的容器,这里使用HashMap装,模仿spring的套路。不作任何处理的粗糙版
public class BeanDefinition {
private Object bean;
public BeanDefinition(Object bean) {
this.bean = bean;
}
public BeanDefinition() {
}
public Object getBean() {
return bean;
}
}
@Data
public class BeanFactory {
//记录bean的处理
//不能直接获取Object因为这个是需要包装的,
//毕竟要统一处理,避免各种瞎依赖
private HashMap<String, BeanDefinition> beanList;
public Object getBean(String beanName) {
return beanList.get(beanName).getBean();
}
}
4.2 略微粗糙版
添加了单例池,设计模式开始有了雏形