实例化Bean
单例bean,并且lazy-init为false(默认是false),则 ApplicationContext在刷新的时候就实例化该Bean,并且将实例化的Bean放到缓存中,下次再使用该Bean的时候, 直接从这个缓存中获取;如果单例bean是懒加载的,即lazy-init为true,则在第一次getBean获取该Bean的时候进行实例化,并放入缓存;scope是prototype的多例bean,每次使用获取Bean的时候都会进行实例化
<bean id="" class="" scope="作用域"/>
1. singleton: 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope)
2. prototype: 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()
3. request: 用于web开发,将Bean放入request范围 , 在同一个request 获得同一个Bean
4. session: 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean
spring容器默认加载bean为非延迟加载,在容器刷新阶段就会实例化bean对象,设置为延迟加载则当类首次被加载时才会初始化实例,所有bean的实例化都是通过getBean去实现
<!--当前xml中所有的bean-->
<beans default-lazy-init="default | false | true">
<!--指定的bean-->
<bean lazy-init="default | false | true">
使用注解方式
@Lazy
public class Bean {}
总结所有bean的生命周期:单例且非延迟加载的bean跟随容器刷新完成实例初始化,之后访问实例从缓存中获取;单例延迟加载的bean在首次访问时通过getBean完成实例化,之后访问从缓存中获取;
Bean实例化的方式
无参数构造器实例化
<bean id="super" name="a1,a2,a3" class="cn.mywork.spring.Super" lazy-init="true"/>
静态工厂方法实例化
//factory-method找到工厂类的静态方法
<bean id="student" class="cn.mywork.spring.StaticFactory" factory-method="getStu"/>
//配置静态工厂类
public class StaticFactory {
//通过配置文件找到静态方法,返回对象为创建的bean
public static Student getStu(){
return new Student();
}
}
ApplicationContext context;
Student student = context.getBean("student", Student.class);
实例工厂
//先将工厂bean交给容器管理
<bean id="instanceFactory" name="fc" class="cn.mywork.wms.spring.InstanceFactory"/>
//factory-bean只能是初始化好的bean对象,通过bean工厂对象,获取实例方法初始化bean
<bean id="student" factory-bean="fc" factory-method="getStu"/>
实现FactoryBean接口,通过getObject方法返回目标实例
//实现getObject方法
public class InstanceFactory implements FactoryBean<Student>{
@Override
public Student getObject() throws Exception {
return new Student();
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
<bean id="student" class="cn.mywork.spring.InstanceFactory"/>
注解的方式
//注解对应的配置解析
<bean id="super" class="cn.mywork.wms.spring.Super" init-method="init" destroy-method="destory" scope="prototype">
<!--注入的属性-->
<property name="sub" ref="sub"/>
</bean>
<bean id="sub" class="cn.mywork.wms.spring.Sub"/>
//默认的为简化的类名,Xml里也同于bean标签的id值
@Component("super")
//作用域:非单例
@Scope("prototype")
public class Super {
private String name;
//注入Sub初始化的实例
@Autowired
private Sub sub;
//初始化的方法,init-method="init"
@PostConstruct
public void init(){
}
//销毁的方法,destroy-method="destory"
@PreDestroy
public void destory(){
}
}
自定义BeanFactory工厂
public class BeanFactoryDemo {
//key为id,value为全限定名
private static Map<String,String> beanMap = new HashMap<>();
//bean缓存,延迟加载bean时,genBean之后将bean放入缓存
private static Map<String,Object> cacheMap = new HashMap<>();
//解析xml配置文件
static {
try {
//getClassLoader().getResourceAsStream是加载resources资源路径下的配置文件
InputStream resource = BeanFactoryDemo.class.getClassLoader().getResourceAsStream("spring.xml");
initBeanMap(resource);
}catch (Exception e){}
}
private static void initBeanMap(InputStream resource) throws Exception {
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(resource,new DefaultHandler(){
//解析后的标签名
private String tagName;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
this.tagName = qName;
//获取标签内容
if ("bean".equals(tagName)){
//获取id的值
String id = attributes.getValue("id");
//获取bean的全限定名
String beanClassName = attributes.getValue("class");
beanMap.put(id,beanClassName);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
tagName = null;
}
});
}
//获取bean实例的方法,延迟加载方式
public static <T> T getBean(String id,Class<T> beanClass) throws Exception{
//只有map中存在的key值才会继续处理
if (beanMap.containsKey(id)){
//再判断缓存中是否有该bean
if (cacheMap.containsKey(id)){
return (T) cacheMap.get(id);
}
String beanClassName = beanMap.get(id);
//加载全限定名,通过反射机制创建bean
Object instance = Class.forName(beanClassName).newInstance();
//判断是否为beanClass类型的实例
if (beanClass.isInstance(instance)){
cacheMap.put(id,instance);
return (T) instance;
}
}
return null;
}
}
Student student = BeanFactoryDemo.getBean("student", Student.class);
getBean
refresh执行到finishBeanFactoryInitialization时才开始实例化非延迟加载的bean,主要看其中的preInstantiateSingletons方法
public void preInstantiateSingletons() throws BeansException {
//所有的需要实例化的beanName都在beanDefinitionNames,包括 Aspectj的, 通过注解标识的
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
//合并父类BeanDefinition
//MergedBeanDefinition合并bean定义,XML 配置来注册 bean,会被封装成GenericBeanDefinition;使用注解的方式来注册 bean,会被封装成 ScannedGenericBeanDefinition,最终统一转换成 RootBeanDefinition处理
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//非抽象,单例,非懒加载三个条件
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是 FactoryBean 类型的对象则加上&
//判断是factoryBean还是普通bean,实现FactoryBean接口的getObject()方法可以定义创建实例对象,比如很多中间件的就是通过这种方式实现
if (isFactoryBean(beanName)) {
bean = getBean(FACTORY_BEAN_PREFIX + beanName);
...
}
else {
// 进入到doGetBean执行实例化bean
bean = getBean(beanName);
}
}
}
}
容器初始化完成还是在初始化之后动态获取bean都会访问beanFacroty.getBean()方法,进入这个方法发现有很多分支去获取bean,如果不是首次获取bean则直接getSingleton()先从缓存中获取
protected <T> T doGetBean(String name, Class<T> requiredType,Object[] args, boolean typeCheckOnly) throws BeansException {
//去掉FactoryBean的前缀“&”,解析别名返回namespace的beanName
String beanName = this.transformedBeanName(name);
//获取缓存中的bean,不涉及创建新的bean实例和解决循环依赖
Object sharedInstance = this.getSingleton(beanName);
Object bean;
//缓存中如果能获取到
if (sharedInstance != null && args == null) {
//普通bean直接返回实例,factoryBean继续处理
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
//和singletonsCurrentlyInCreation类似存放正在创建的Prototype实例
//循环依赖校验:当前原型实例池中有正在创建的对象了,说明这个对象是个原型对象,并且当前线程中这个对象已经处于创建中了,会造成循环依赖
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
//当前BeanFactory中的beanDefinitionMap找不到当前Bean,则从parentBeanFactory获取
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
//解析别名和去掉FactoryBean的前缀
String nameToLookup = this.originalBeanName(name);
//使用父类的doGetBean方法实例化bean
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
...
}
//类型检测默认为false,将beanName添加到alreadyCreated缓存
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
//RootBeanDefinition可以理解为一个没有parent的独立BeanDefinition
//Map<String, RootBeanDefinition> mergedBeanDefinitions
//如果mergedBeanDefinitions没有父类定义就是BeanDefinition本身
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
//检查是抽象类则抛异常
this.checkMergedBeanDefinition(mbd, beanName, args);
//获取所有当前bean的依赖,需要在依赖创建之后才能进行实例创建
//@DependsOn这个熟悉的注解:需要依赖另一个bean的实例创建
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查是否依赖于beanName,即存在循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException();
}
//将dep和beanName的依赖关系注册到dependentBeanMap中
registerDependentBean(dep, beanName);
//先实例化依赖的Bean
getBean(dep);
}
//实例化不同的scope域的Bean
if (mbd.isSingleton()) {
//重载方法
//getSingleton(String beanName, ObjectFactory<?> singletonFactory)
sharedInstance = this.getSingleton(beanName, () -> {
//singletonFactory.getObject()方法最终执行的是createBean()方法
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
//跟上面一样不是factoryBean则返回普通的实例对象
bean = this.getObjectForBeanInstance(sharedInstance,name,beanName, mbd);
} else if (mbd.isPrototype()) {
//scope为prototype的bean创建
var11 = null;
Object prototypeInstance;
try {
//添加到缓存prototypesCurrentlyInCreation中
this.beforePrototypeCreation(beanName);
//创建实例
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
//移除prototypesCurrentlyInCreation中的缓存
this.afterPrototypeCreation(beanName);
}
//普通Bean直接返回
bean=this.getObjectForBeanInstance(prototypeInstance,name,beanName, mbd);
} else {
//其他scope的bean创建
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
//实现的也是ObjectFactory
Object scopedInstance = scope.get(beanName, () -> {
//通过getObject方法调用,和prototype创建bean实例一致
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);
}
}
}
}...
factoryBean
回到doGetBean()方法,如果获取到缓存则继续进入getObjectForBeanInstance()交给factoryBean处理
//bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//表示name以“&”为前缀但不是factoryBean则抛异常
if (BeanFactoryUtils.isFactoryDereference(name)) {
...
//不是factoryBean则直接返回
} else if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
} else {
//缓存中拿到的是一个factoryBean
Object object = null;
if (mbd != null) {
//标注这个beanDefinition为factoryBean
mbd.isFactoryBean = true;
} else {
//入参mbd为null,所以需要从factoryBeanObjectCache缓存拿到实例
//Map<String, Object> factoryBeanObjectCache 用于缓存factoryBean
object = this.getCachedObjectForFactoryBean(beanName);
}
//缓存中也没有
if (object == null) {
FactoryBean<?> factory = (FactoryBean)beanInstance;
//从beanDefinitionMap注册的缓存中找到beanDefinition
if (mbd == null && this.containsBeanDefinition(beanName)) {
//获取合并(父容器)后的RootBeanDefinition
mbd = this.getMergedLocalBeanDefinition(beanName);
}
//mbd是否是合成的,一般为false
boolean synthetic = mbd != null && mbd.isSynthetic();
//使用factory去实例化bean
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
}
factoryBean是一个特殊的bean,实现FactoryBean接口,factoryBean在被初始化时会调用其getObject()方法创建应用的bean
//注入一个factoryBean
@Component
public class MyFactoryBean implements FactoryBean<HahaBean> {
@Override
public HahaBean getObject() throws Exception {
//比如通过getBean(MyFactoryBean.class)则会返回hahaBean实例
return new HahaBean();
}
@Override
public Class<?> getObjectType() {
return HahaBean.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
//getBean()会通过doGetBean方法获取bean实例
public class SingleManApp {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(StartUp.class);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
HahaBean myFactoryBean = (HahaBean) beanFactory.getBean("myFactoryBean");
myFactoryBean.test();
}
}
@SpringBootApplication
public class StartUp {
}
//最终返回的实例
public class HahaBean {
public void test(){
System.out.println("hahabean");
}
}
dependsOn
Spring提供比如@DependsOn/depends-on用于控制bean初始化顺序,为了便于理解就不以’依赖’表示bean的关系,而是从逻辑上出发,A depends-on B,A的实例化需要B,则B优先于A进行实例化
// 检查是否存在类似于A depondson B,而B depends-on A 的情况
if (isDependent(beanName, dep)) {
throw new BeanCreationException();
}
//将dep和beanName的depends-on关系注册到dependentBeanMap中
registerDependentBean(dep, beanName);
//先实例化当前bean depends-on的Bean
getBean(dep);
首先判断是否存在循环depends-on,保证不存在死循环问题,比如A dep B,B dep C,C dep A
//dependentBeanMap存放的是depends-on当前bean的实例集合
Map<String, Set<String>> dependentBeanMap;
//dependenciesForBeanMap存放当前优先于当前bean初始化的
Map<String, Set<String>> dependenciesForBeanMap;
//alreadySeen默认为null表示还没有检查过
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
//表示已经检查过了
if (alreadySeen != null && ((Set)alreadySeen).contains(beanName)) {
return false;
} else {
//如果是别名则解析别名
String canonicalName = this.canonicalName(beanName);
//dependentBeanMap这个集合存放的bean应该是在当前bean实例化之后才进行初始化
Set<String> dependentBeans = (Set)this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
//但是dependentBeanName应该优先实例化的bean却在dependentBeans中这就会造成死循环
} else if (dependentBeans.contains(dependentBeanName)) {
return true;
//这一步就是彻底找到 A - B,B - C,C - D,D - A 这种隔层 depends-on
} else {
Iterator var6 = dependentBeans.iterator();
String transitiveDependency;
do {
if (!var6.hasNext()) {
return false;
}
transitiveDependency = (String)var6.next();
if (alreadySeen == null) {
alreadySeen = new HashSet();
}
((Set)alreadySeen).add(beanName);
} while(!this.isDependent(transitiveDependency, dependentBeanName, (Set)alreadySeen));
return true;
}
}
}
registerDependentBean:在实例化优先的bean实例之前还需要将相互顺序关系进行维护
//注意入参registerDependentBean(dep, beanName),实际deponds-on的bean位置换成了beanName
//为了方便理解还是按照依赖顺序将首先实例化的称为A(beanName),dependentBeanName称为B
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = this.canonicalName(beanName);
// depends-on Bean的映射集合
Map var4 = this.dependentBeanMap;
//depends-on A的集合(顺序在A之后)
Set dependenciesForBean;
synchronized(this.dependentBeanMap) {
//java8新方法computeIfAbsent方法用来计算给定key,返回value映射值。如果,key并没有映射到一个值,或者映射到null,那么,就用这个value值放到这个hashmap中
//获取deponds-on A的集合
dependenciesForBean = (Set)this.dependentBeanMap
.computeIfAbsent(canonicalName, (k) -> {
return new LinkedHashSet(8);
});
//将B维护到deponds-on A的集合
if (!dependenciesForBean.add(dependentBeanName)) {
return;
}
}
//Bean depends-on的集合映射
var4 = this.dependenciesForBeanMap;
synchronized(this.dependenciesForBeanMap) {
//获取B depends-on的集合,并将A维护进去
dependenciesForBean = (Set)this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, (k) -> {
return new LinkedHashSet(8);
});
dependenciesForBean.add(canonicalName);
}
}
getSingleton
单例bean的实例化流程
1.解析别名(如果有)获取bean的名字
2.如果scope为sigleton则从缓存中查询是否有这个bean,否则跳过
3.首次获取bean通过getSingleton创建bean的实例
4.标记这个bean已经被创建了(允许循环依赖则Spring通过三级缓存解决,提前将bean曝光)
5.递归获取依赖的bean并完成实例化
6.当前bean进行属性注入
在非懒加载bean随容器启动时,载单例bean首次访问时进行实例化,通过调用getBean访问getSingleton
if (mbd.isSingleton()) {
//入参ObjectFactory通过getObject获取最终的实例
sharedInstance = this.getSingleton(beanName, () -> {
try {
//实现ObjectFactory接口的getObject()方法
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
//判断创建的bean是否为factoryBean,如果是则通过factoryBean去创建实例
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
Spring三级缓存解决循环依赖
只有单例bean且在earlySingletonExposure为true时(默认为true)才允许循环依赖的情况下才有二三级缓存
Spring 能解决的循环依赖有:通过 setter 注入的循环依赖、通过属性注入的循环依赖,当构造器出现循环依赖则无法解决,所以需要先用构造函数创建一个 “不完整” 的 bean 实例
//singletonObjects 一级缓存:实例化保存的单例 bean 对象
private final Map<String, Object> singletonObjects;
//earlySingletonObjects 二级缓存:还未进行属性填充
private final Map<String, Object> earlySingletonObjects;
//singletonFactories 三级缓存:存放BeanName与bean工厂
private final Map<String, ObjectFactory<?>> singletonFactories;
//在Bean开始实例化时将bean存放,创建完成时会将其移出
private final Set<String> singletonsCurrentlyInCreation;
//Bean被创建完成后添加
private final Set<String> alreadyCreated;
//已经注册的单例bean,三级缓存中任意添加了都会同步添加到这里
private final Set<String> registeredSingletons
解决循环依赖的原理
1.满足条件下,比如有两个bean A和B循环依赖,在A实例化getBean时会暴露到三级缓存中,进行属性注入populate时发现依赖B,则先去实例化B;
2.B实例化过程中也会暴露到三级缓存中,在注入属性时又发现依赖于A;
3.此时再次访问getBean(A),由于A已经存在三级缓存,所以在获取A缓存时通过三级缓存获取A的原始bean添加到二级缓存中,并返回缓存的A实例,A注入到B;
4.B完成属性注入之后放入一级缓存中,然后A完成了属性的注入并获取了二级缓存,清除二级缓存放入一级缓存
singleton实例由实现ObjectFactory接口getObject方法返回createBean()实现
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
//还是先从缓存中拿
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//当前bean是正在destruction状态,默认false
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException();
}
//创建实例前的验证
//先校验beanName不是要在创建检查排除掉的(inCreationCheckExclusions缓存)
//且添加到正在创建bean的缓存singletonsCurrentlyInCreation中,添加失败就表示已存在
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
//执行creatBean()方法,由入参singletonFactory中getObject方法返回
//如果运行循环依赖则返回的是二级缓存
singletonObject = singletonFactory.getObject();
newSingleton = true;
} finally {
//从singletonsCurrentlyInCreation移除beanName
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
/**创建新的Bean成功添加到一级缓存中,并移除二三级缓存
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName); //已注册的bean
**/
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
当earlySingletonExposure为true表示允许循环依赖从而添加一个三级缓存ObjectFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {
RootBeanDefinition mbdToUse = mbd;
//...
//当存在InstantiationAwareBeanPostProcessor时执行处理器的applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization
Object beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
//返回完整的Bean实例
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
//bean包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果是factoryBean则清除缓存
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建Bean实例,进行包装,实现构造器依赖注入
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
//获取原始对象和其类型
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//MergedBeanDefinitionPostProcessor,处理RootBeanDefinition
//@Autowired通过子类AutowiredAnnotationBeanPostProcessor实现将标有注解的字段和方法放入缓存
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
//满足单例,允许循环依赖,正在实例创建中三个条件
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
//解决循环依赖,添加三级缓存singletonFactory,移出二级缓存
//this.singletonFactories.put(beanName, singletonFactory);
//this.earlySingletonObjects.remove(beanName);
//this.registeredSingletons.add(beanName);
this.addSingletonFactory(beanName, () -> {
//实现SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
//可以实现AOP的逻辑,如果没有增强处理则三级缓存就是原始的bean
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
//完成属性和方法的依赖注入
this.populateBean(beanName, mbd, instanceWrapper);
//bean增强,@PostConstruct>InitializingBean>init()
//依次:处理aware接口,执行BeanPostProcessors中postProcessBeforeInitialization方法,调用初始化方法init-Methods,执行BeanPostProcessor的postProcessAfterInitialization方法
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
//解决循环依赖
if (earlySingletonExposure) {
//调用重载的方法,在获取缓存时也访问的是这个方法,用于获取二级缓存
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
//initializeBean没有处理bean则将二级缓存进行进行暴露
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
//initializeBean处理之后会产生一个代理对象且有被依赖的bean
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
//将这些依赖exposedObject的bean数组移除,因为Bean已经不是原来的bean了
String[] dependentBeans = this.getDependentBeans(beanName);
...
}
}
}
//注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
通过三级缓存singletonObject获取二级缓存的重载的方法
---DefaultSingletonBeanRegistry
//allowEarlyReference表示是否允许从singletonFactories中通过getObject拿到对象,默认true
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
//isSingletonCurrentlyInCreation表示正在进行创建中,且从一级缓存中未获取到实例
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存也不存在且允许循环依赖
if (singletonObject == null && allowEarlyReference) {
//获取ObjectFactory,从实例工厂获取实例
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
//允许循环依赖则会存在一个三级缓存
if (singletonFactory != null) {
//通过这个三级缓存的getObject()方法实现,如果没有增强处理则是原始bean
singletonObject = singletonFactory.getObject();
//获取到了则添加到二级缓存中,并移除三级缓存的对象
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
//这个getSingleton方法的重载就是从缓存获取bean实例,没有则去创建新的实例
return singletonObject;
}
prototypes实例的创建
多例的缓存放在ThreadLocal缓存中,每个线程获取的都是通过getBean实例化的新对象,将 beanName 添加到 prototypesCurrentlyInCreation 缓存
private final ThreadLocal<Object> prototypesCurrentlyInCreation;
try {
//实例化之前先添加缓存到当前线程中
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
//清除当前线程的缓存
this.afterPrototypeCreation(beanName);
}
protected void beforePrototypeCreation(String beanName) {
//prototype的bean的beanName集合
Object curVal = this.prototypesCurrentlyInCreation.get();
// 将ThreadLocal设置成当前的beanName
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
// 如果缓存不为空且为String类型,则表示只有一个beanName
else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<String>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
// 如果存在多个beanName,将当前的beanName添加到Set
else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
}
initializeBean的顺序
完成属性注入之后执行initializeBean,先说结论,先通过处理器执行@PostConstruct注解标注的方法,通过invokeInitMethods先执行InitializingBean接口的afterPropertiesSet()方法,最后才执行init-method方法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//如果bean是aware实现类,则将beanName,beanFactory分别添加到BeanNameAware和BeanFactoryAware
this.invokeAwareMethods(beanName, bean);
Object wrappedBean;
//执行BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization方法
//InitDestroyAnnotationBeanPostProcessor在这一步会执行@PostConstruct标注的方法
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 处理InitializingBean和init-method
this.invokeInitMethods(beanName, wrappedBean, mbd);
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
执行InitDestroyAnnotationBeanPostProcessor处理器时找到并invoke被标注的方法
//在方法上通过注解@PostConstruct标注为初始化的方法
//标注为初始化的方法
@PostConstruct
public void init(){
System.out.println("init");
}
//销毁的方法
@PreDestroy
public void destroy(){
System.out.println("destroy");
}
进入invokeInitMethods方法,首先会判断bean是否实现了InitializingBean,如果是则执行afterPropertiesSet()方法.下一步从initMethods获取init的方法,init-method是在xml解析时封装在beanDefinition的initMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
//InitializingBean实现类完成初始化方法
boolean isInitializingBean = bean instanceof InitializingBean;
((InitializingBean)bean).afterPropertiesSet();
//init-method指定的初始化方法
String initMethodName = mbd.getInitMethodName();
this.invokeCustomInitMethod(beanName, bean, mbd);
}
//实现InitializingBean接口的afterPropertiesSet方法
@Service
public class TxService implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean");
}
}
也可以通过@Bean指定init-method方法:
@Bean(initMethod = "init")
public InitService getInit(){
return new InitService();
}
public class InitService {
public void init(){
System.out.println("init");
}
}
属性注入
DI目的是在初始化对象时,根据对象中的属性依赖, 动态将容器中bean按需注入进去,无需手动维护依赖关系,比如两个交给spring管理的bean,其中A依赖B,这时就需要先实例化B并注入到A中,实现属性填充;
构造器注入
首先要回到doCreateBean方法中有一个createBeanInstance就是用于构造器注入
//构造器实例化
Object instance = constructor.newInstance();
根据beanName、mbd创建Bean实例,args是bean的构造函数参数,根据args选择不同的构造函数
//进入doCreateBean方法,通过createBeanInstance创建beanDefinition对应的包装实例
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//ClassUtils.forName(className, dynamicLoader);
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
//理解为提供一个静态方法回调创建实例,比如static MyBean createMyBean(){new MyBean();}
//beanDefinition.setInstanceSupplier(SupplierBean::createUser);
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
//使用工厂方法去创建实例
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
//不为null,则表示缓存有被解析的构造器
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//判断是否需要自动注入,默认是false
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
//args为null
if (resolved) {
//true构造函数自动注入,false选择使用默认的构造函数
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
}
//SmartInstantiationAwareBeanPostProcessor选择候选的构造函数
//@Autowired就是通过子类AutowiredAnnotationBeanPostProcessor实现注入
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,执行构造函数自动注入
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
//理解为public的构造器
ctors = mbd.getPreferredConstructors();
//autowireConstructor自动注入的选举流程:优先public方法,根据入参的args参数个数(做解析返回最终的参数个数)找到符合参数大于或等于的候选构造器,instantiateBean没有args参数当然默认使用无参构造器;和autowireConstructor一样最后通过BeanUtils.instantiateClass(ctor, args)构建原始实例;
return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
determineConstructorsFromBeanPostProcessors方法用于执行determineCandidateConstructors方法,主要的实现类有AutowiredAnnotationBeanPostProcessor,看处理器名字就知道是处理@Autowired,主要作用也是用于给定 bean 的候选构造函数,因为源码很长,包括处理器是如何加载到容器中,暂时留个坑,大致理解一下处理器determineCandidateConstructors方法的作用
1.处理@Lookup注解,如果一个单例BeanA依赖多例的BeanB,因为BeanA是单例,在初始化一次之后就放入缓存,所以BeanB也是beanA首次初始化依赖的beanB时所创建的实例;使用@Lookup注解标注在构造器方法或者普通方法用于生成子类去重写这个方法,每次调用时会去调子类则形成依赖的更新;将@Lookup方法添加到lookupMethodsChecked缓存
2.从candidateConstructorsCache.get(beanClass)缓存中获取已存在解析的构造器,否则继续通过放射方法getDeclaredConstructors获取类的所有构造器放入rawCandidates缓存
3.遍历所有构造器并进行分类缓存:
// 存放@Autowire注解的构造函数
List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
// 存放@Autowire注解,并且require=true的构造函数
Constructor<?> requiredConstructor = null;
// 存放默认的构造函数
Constructor<?> defaultConstructor = null;
4.如果不存在required=true则将默认构造器放入candidates,然后将集合转为Constructor<?>[]数组,如果只有构造器且非默认则单独放入候选构造器数组,其他情况返回空new Constructor<?>[0]数组,封装到构造器缓存
以一个简单的实例来理解整个构造器注入依赖的流程:constructor-arg解析封装在ConstructorArgumentValues中,所以ConstructorArgumentValues有值时通过autowireConstructor方法选择构造器进行实例化,优先选择public作为候选构造器,获取到依赖的属性通过resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues)去创建依赖的sub实例,@Autowired用在构造器上主要是获取候选构造器
public class Super {
private String name;
private Sub sub;
//构造器
public Super(String name, Sub sub) {
this.name = name;
this.sub = sub;
}
}
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//当获取getBean时开始实例化
Object aSuper = context.getBean("super");
<!--构造器方式注入constructor-arg-->
<bean id="super" class="cn.mywork.spring.Super">
<constructor-arg name="name" value="superName"/>
<constructor-arg name="sub" ref="sub"/>
</bean>
<!--注入的对象-->
<bean id="sub" class="cn.mywork.spring.Sub">
<property name="age" value="30"/>
</bean>
属性自动装配
如果是byName注入模式,则通过autowireByName方法调用getBean实例化依赖的Bean并注入到当前Bean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//PropertyValues对bean的属性值的封装,比如依赖的bean信息
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
/*AutowireMode自动装配类型
int AUTOWIRE_NO = 0; 默认装配模式,注解注入的方式
int AUTOWIRE_BY_NAME = 1; 通过beanName注入依赖
int AUTOWIRE_BY_TYPE = 2; 根据bean类型注入
int AUTOWIRE_CONSTRUCTOR = 3; 构造器注入
*/
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
/* 自动装配byName,将sub注入到Super中,只需要保证sub的beanName和属性名一致即可
public class Super{
private Sub sub1;
}
<bean id="super" class="com.xxx.Super" autowire="byName">
<bean id="sub1" class="com.xxx.Sub">
*/
//获取依赖的属性名称作为beanName去getBean,再将依赖关系注册到bean的dependy-on的缓存中
this.autowireByName(beanName, mbd, bw, newPvs);
}
/* 自动装配byType,通过sub属性类型Sub.class去匹配sub的bean并进行注册
通过doResolveDependency方法就是@Autowired查找bean的第一个方式,找到class类型对应
的所有bean,再根据条件进行筛选的依赖的bean注入,并将依赖关系注册到缓存中
*/
if (resolvedAutowireMode == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//执行存在InstantiationAwareBeanPostProcessor的postProcessProperties方法
//处理@Autowire标注的属性注入
while(...) {
pvs = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
}
//property属性注入
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
注解@Autowired注入原理
回到doCreateBean,当构造器注入完成后继续往下执行applyMergedBeanDefinitionPostProcessors(),这个方法用于处理MergedBeanDefinitionPostProcessor处理器的postProcessMergedBeanDefinition,实现该处理器会将合并的BeanDefinition作为方法的参数进行增强
这一步的主要作用就是将被@Autowired标注的set方法和字段信息封装到metadata
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
//子类AutowiredAnnotationBeanPostProcessor的实现,处理@Autowired
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//在指定Bean中查找使用@Autowire注解的元数据
//获取字段和set方法上的@Autowired注解信息(不支持static修饰的字段和方法)
//方法获取descriptor.getWriteMethod()判断是否为set方法
//method、required、pd封装成AutowiredMethodElement添加到InjectionMetadata缓存
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
回到populateBean方法,完成byName自动装配后往下执行,通过postProcessProperties方法用于完成被@Autowired标注的属性注入/方法注入,实现注入的方法inject()有两个实现类,分别用于set方法和字段属性注入
protected void inject(Object target, String beanName, PropertyValues pvs) {}
字段属性注入优先通过属性的name作为BeanName去找bean缓存,如果没有缓存则根据classType去获取bean,在doResolveDependency方法中会进行详细查找依赖bean的过程:根据名称快速查找缓存,没有缓存则通过findAutowireCandidates根据类型 type 查找名称 beanNames作为候选,通过@Qualifier值进行筛选,和选择候选构造器一样;如果候选者个数大于1则继续判断@Primary(表示优先)和@Priority(数字越小优先级越高),从而选出最终注入的bean
// 设置字段访问性
ReflectionUtils.makeAccessible(field);
// 通过反射为属性赋值,将解析出来的bean实例赋值给field
field.set(bean, value);
@Resource先找默认的bean id(bean注册的时候不指定beanId则默认为类的简单名),如果接口有多个实现,则使用@Resource(name = “”)去指定,当注入的实例有多个实现类时,使用Resource
方法的注入:必须是set方法,在封装metadata时就通过内省的方式判断注解标注的方法是否为writeMethod(也就是set方法)
//内省机制
BeanInfo beanInfo = Introspector.getBeanInfo(superClass);
PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : ps){
if (pd.getName().equals("name")){
//set方法
pd.getWriteMethod();
}
}
//设置set方法的访问性
ReflectionUtils.makeAccessible(method);
//通过反射执行方法
method.invoke(bean, value);
PropertyValues属性注入
populateBean方法最后一步applyPropertyValues将所有PropertyValues中的属性填充到bean中,比如通过xml配置属性依赖注入,在loadBeanDefinitions解析配置项时便将属性值封装在PropertyValues中
<!-- 配置setter属性注入的标签为property->
<bean id="student" class="cn.mywork.spring.Student">
<!--直接将值用value属性填入-->
<property name="name" value="studentName"/>
<!--对象引入,需要ref去引入bean的id-->
<property name="sub" ref="sub"/>
<!--基本类型的数组注入 array标签-->
<property name="nums">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<!--对象集合的注入list标签-->
<property name="subList">
<list>
<ref bean="sub"/>
<ref bean="sub"/>
</list>
</property>
<!--map集合的注入 map标签-->
<property name="superMap">
<map>
<entry key="key1" value-ref="super"/>
<entry key="key2" value-ref="super"/>
</map>
</property>
</bean>
<!--注入的属性-->
<bean id="sub" class="cn.mywork.spring.Sub">
<property name="age" value="20"/>
</bean>
<bean id="super" class="cn.mywork.spring.Super">
<property name="name" value="superName"/>
</bean>
解析配置项的property属性类型,返回对应类型的值,核心方法就是setPropertyValues在很深入的内部进行实现,有BeanPropertyHandler方法注入和FieldPropertyHandler字段注入两种实现
//set方法进行属性注入
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(BeanWrapperImpl.this.getWrappedInstance(), new Object[]{value});
//字段属性注入
ReflectionUtils.makeAccessible(this.field);
this.field.set(DirectFieldAccessor.this.getWrappedInstance(), value);