这篇文章主要讲解了“Spring中加载Bean的使用方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring中加载Bean的使用方法”吧!
从网站建设到定制行业解决方案,为提供成都网站设计、成都网站制作服务体系,各种行业企业客户提供网站建设解决方案,助力业务快速发展。创新互联将不断加快创新步伐,提供优质的建站服务。
// 前面两篇已经分析了读取配置文件,并注册BeanDefinition
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));// 这篇分析加载Bean
MyTestBean bean = bf.getBean("myTestBean", MyTestBean.class);publicT getBean(String name, Class requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); }
protectedT doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly){ //转换对应的beanName,先是去除FactoryBean的修饰符&,取指定alias所表示的最终beanName(如果存在的话) final String beanName = transformedBeanName(name); Object bean; //1.检查缓存中或者实例工厂中是否有对应的实例 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //2.返回对应的实例,如附录中的FactoryBean例子,上面的sharedInstance是CarFactoryBean的实例,但是 //实际应当返回Car实例,因此在该方法中会做处理 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //只有在单例情况下才尝试解决循环依赖,否则直接抛异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //如果beanDefinitionMap不存在beanName则尝试从parentBeanFactory中寻找 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); }else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //如果存在依赖则需要递归实例化依赖的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dependsOnBean : dependsOn) { getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } //3.获取单例的bean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory
步骤1: Object sharedInstance = getSingleton(beanName);
public Object getSingleton(String beanName) {
//参数true表示设置允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//首先尝试从缓存中加载,singletonObjects = new ConcurrentHashMap(64);
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果为空,则锁定全局变量进行处理
synchronized (this.singletonObjects) {
//如果此bean正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预先设定的getObject方法
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
} 步骤2: bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
//验证,若指定的name是工厂相关,以&开头,又不是FactoryBean类型则验证不通过
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)){
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
//是正常的bean直接返回,或者用户想取的就是FactoryBean类型的bean(name以&开头)则直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)){
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
//从缓存中获取
FactoryBean> factory = (FactoryBean>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}步骤3:获取单例的bean
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
//全局变量上锁
synchronized (this.singletonObjects) {
//检查缓存中是否已经创建,如果为空才可以初始化
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//记录加载状态,关键的一步,将正在创建的bean放入singletonsCurrentlyInCreation,用于检测循环依赖
beforeSingletonCreation(beanName);
try {
//通过传入的singletonFactory实例化bean,回调
singletonObject = singletonFactory.getObject();
}
catch (BeanCreationException ex) {}
finally {
//和记录加载状态相反,创建完成之后移除正在加载的记录
afterSingletonCreation(beanName);
}
//创建完成之后,将其放入缓存中,并删除加载bean过程中的各种辅助状态
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.containsKey(beanName) &&
this.singletonsCurrentlyInCreation.put(beanName, Boolean.TRUE) != null) {
throw new BeanCurrentlyInCreationException(beanName);
}
}protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
//上述回调进行bean的创建
singletonObject = singletonFactory.getObject();
public Object getObject() throws BeansException {
return createBean(beanName, mbd, args);
}
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args){
try {
//1.处理lookup-method和replace-method,bean实例化的时候若检测到有methodOverides属性,会动态地
//为当前bean生成代理并使用对应的拦截器为bean做增强处理,相关逻辑在bean实例化时会分析,此处仅是做下校验
mbd.prepareMethodOverrides();
}
try {
//给BeanPostProcessors一个机会来返回代理替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbd);
//短路,若经过处理的bean不为空,则直接返回代理的bean,AOP功能就是基于这里的判断,后面分析
if (bean != null) {
return bean;
}
}
//进行常规bean的创建
Object beanInstance = doCreateBean(beanName, mbd, args);
return beanInstance;
}protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
BeanWrapper instanceWrapper = null;
//如果是单例要清除缓存
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//实例化Bean,将BeanDefinition转换为BeanWrapper,该过程比较复杂
//a、存在工厂方法就使用工厂方法初始化
//b、若有多个构造函数,则根据参数锁定构造函数初始化
//c、若既不存在工厂方法,也不存在带参构造函数,则使用默认构造函数初始化
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//...省略后续代码,先分析createBeanInstance
}protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//解析beanClass
Class> beanClass = resolveBeanClass(mbd, beanName);
//1.若存在工厂方法,就使用工厂方法初始化并返回,工厂方法用例见附录2
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
//若不存在工厂方法则使用构造函数初始化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果已经解析缓存了,则直接调用构造函数初始化
if (resolved) {
if (autowireNecessary) {
//使用带参构造函数初始化
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认构造函数
return instantiateBean(beanName, mbd);
}
}
//需要根据参数解析构造函数
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//带参构造函数
return autowireConstructor(beanName, mbd, ctors, args);
}
//默认构造函数
return instantiateBean(beanName, mbd);
}1、使用工厂方法初始化 经过一系列处理,使用工厂方法初始化最终会调用到此处

beanInstance = beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, factoryBean, factoryMethodToUse, argsToUse);
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Object factoryBean, final Method factoryMethod, Object[] args) {
ReflectionUtils.makeAccessible(factoryMethod);
//使用反射调用工厂方法
return factoryMethod.invoke(factoryBean, args);
}
public Object invoke(Object obj, Object... args){
MethodAccessor ma = methodAccessor;
//debug时发现此处会调用工厂方法
return ma.invoke(obj, args);
}
public static FactoryMethodBean getInstance(){
return new FactoryMethodBean();
}2、使用带参构造函数初始化,无参构造函数更简单,因为不需要定位构造函数,创建对象类似使用带参构造函数初始化,最终会调用到此处.

beanInstance = this.beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
final Constructor> ctor, Object[] args) {
//如果有需要覆盖或者动态替换的方法则使用CGLIB动态代理,可以在创建代理的同时动态将方法织如类中
if (beanDefinition.getMethodOverrides().isEmpty()) {
//如果没有直接调用反射来构造实例对象
return BeanUtils.instantiateClass(ctor, args);
}
else {
return instantiateWithMethodInjection(beanDefinition, beanName, owner, ctor, args);
}
}public staticT instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException { try { ReflectionUtils.makeAccessible(ctor); //调用反射进行构造对象 return ctor.newInstance(args); } }
附录 1、FactoryBean的使用
public interface FactoryBean{ //核心方法,让实现类实现的,返回由FactoryBean创建的bean实例 T getObject() throws Exception; Class> getObjectType(); boolean isSingleton(); }
public class Car {
private int maxSpeed;
private String brand;
private double price;
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}public class CarFactoryBean implements FactoryBean{ private String carInfo; public Car getObject() throws Exception { Car car = new Car(); String[] infos = carInfo.split(","); car.setBrand(infos[0]); car.setMaxSpeed(Integer.valueOf(infos[1])); car.setPrice(Double.valueOf(infos[2])); return car; } public Class> getObjectType() { return Car.class; } public boolean isSingleton() { return true; } public String getCarInfo() { return carInfo; } public void setCarInfo(String carInfo) { this.carInfo = carInfo; } }
当调用getBean时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean接口,这时Spring容器就调用接口方法getObject() 返回Bean实例.如果希望获取CarFactoryBean的实例,需要使用getBean(beanName)方法时在beanName前显示加上&前缀,例如 getBean(“&car”).
2、工厂方法factory-method
public class FactoryMethodBean {
private String str = "lwh sayHello";
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public static FactoryMethodBean getInstance(){
return new FactoryMethodBean();
}
}感谢各位的阅读,以上就是“Spring中加载Bean的使用方法”的内容了,经过本文的学习后,相信大家对Spring中加载Bean的使用方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!