這篇文章主要講解了“Spring中加載Bean的使用方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Spring中加載Bean的使用方法”吧!
從網(wǎng)站建設(shè)到定制行業(yè)解決方案,為提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作服務(wù)體系,各種行業(yè)企業(yè)客戶提供網(wǎng)站建設(shè)解決方案,助力業(yè)務(wù)快速發(fā)展。創(chuàng)新互聯(lián)將不斷加快創(chuàng)新步伐,提供優(yōu)質(zhì)的建站服務(wù)。
// 前面兩篇已經(jīng)分析了讀取配置文件,并注冊(cè)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){ //轉(zhuǎn)換對(duì)應(yīng)的beanName,先是去除FactoryBean的修飾符&,取指定alias所表示的最終beanName(如果存在的話) final String beanName = transformedBeanName(name); Object bean; //1.檢查緩存中或者實(shí)例工廠中是否有對(duì)應(yīng)的實(shí)例 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //2.返回對(duì)應(yīng)的實(shí)例,如附錄中的FactoryBean例子,上面的sharedInstance是CarFactoryBean的實(shí)例,但是 //實(shí)際應(yīng)當(dāng)返回Car實(shí)例,因此在該方法中會(huì)做處理 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //只有在單例情況下才嘗試解決循環(huán)依賴,否則直接拋異常 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); //如果存在依賴則需要遞歸實(shí)例化依賴的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) { //參數(shù)true表示設(shè)置允許早期依賴 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)) { //如果為空,則鎖定全局變量進(jìn)行處理 synchronized (this.singletonObjects) { //如果此bean正在加載則不處理 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //調(diào)用預(yù)先設(shè)定的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) { //驗(yàn)證,若指定的name是工廠相關(guān),以&開(kāi)頭,又不是FactoryBean類型則驗(yàn)證不通過(guò) if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)){ throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } //是正常的bean直接返回,或者用戶想取的就是FactoryBean類型的bean(name以&開(kāi)頭)則直接返回 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) { //檢查緩存中是否已經(jīng)創(chuàng)建,如果為空才可以初始化 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //記錄加載狀態(tài),關(guān)鍵的一步,將正在創(chuàng)建的bean放入singletonsCurrentlyInCreation,用于檢測(cè)循環(huán)依賴 beforeSingletonCreation(beanName); try { //通過(guò)傳入的singletonFactory實(shí)例化bean,回調(diào) singletonObject = singletonFactory.getObject(); } catch (BeanCreationException ex) {} finally { //和記錄加載狀態(tài)相反,創(chuàng)建完成之后移除正在加載的記錄 afterSingletonCreation(beanName); } //創(chuàng)建完成之后,將其放入緩存中,并刪除加載bean過(guò)程中的各種輔助狀態(tài) 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); } } //上述回調(diào)進(jìn)行bean的創(chuàng)建 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實(shí)例化的時(shí)候若檢測(cè)到有methodOverides屬性,會(huì)動(dòng)態(tài)地 //為當(dāng)前bean生成代理并使用對(duì)應(yīng)的攔截器為bean做增強(qiáng)處理,相關(guān)邏輯在bean實(shí)例化時(shí)會(huì)分析,此處僅是做下校驗(yàn) mbd.prepareMethodOverrides(); } try { //給BeanPostProcessors一個(gè)機(jī)會(huì)來(lái)返回代理替代真正的實(shí)例 Object bean = resolveBeforeInstantiation(beanName, mbd); //短路,若經(jīng)過(guò)處理的bean不為空,則直接返回代理的bean,AOP功能就是基于這里的判斷,后面分析 if (bean != null) { return bean; } } //進(jìn)行常規(guī)bean的創(chuàng)建 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); } //實(shí)例化Bean,將BeanDefinition轉(zhuǎn)換為BeanWrapper,該過(guò)程比較復(fù)雜 //a、存在工廠方法就使用工廠方法初始化 //b、若有多個(gè)構(gòu)造函數(shù),則根據(jù)參數(shù)鎖定構(gòu)造函數(shù)初始化 //c、若既不存在工廠方法,也不存在帶參構(gòu)造函數(shù),則使用默認(rèn)構(gòu)造函數(shù)初始化 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } //...省略后續(xù)代碼,先分析createBeanInstance }
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { //解析beanClass Class> beanClass = resolveBeanClass(mbd, beanName); //1.若存在工廠方法,就使用工廠方法初始化并返回,工廠方法用例見(jiàn)附錄2 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } //若不存在工廠方法則使用構(gòu)造函數(shù)初始化 boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } //如果已經(jīng)解析緩存了,則直接調(diào)用構(gòu)造函數(shù)初始化 if (resolved) { if (autowireNecessary) { //使用帶參構(gòu)造函數(shù)初始化 return autowireConstructor(beanName, mbd, null, null); } else { //使用默認(rèn)構(gòu)造函數(shù) return instantiateBean(beanName, mbd); } } //需要根據(jù)參數(shù)解析構(gòu)造函數(shù) Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { //帶參構(gòu)造函數(shù) return autowireConstructor(beanName, mbd, ctors, args); } //默認(rèn)構(gòu)造函數(shù) return instantiateBean(beanName, mbd); }
1、使用工廠方法初始化 經(jīng)過(guò)一系列處理,使用工廠方法初始化最終會(huì)調(diào)用到此處
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); //使用反射調(diào)用工廠方法 return factoryMethod.invoke(factoryBean, args); } public Object invoke(Object obj, Object... args){ MethodAccessor ma = methodAccessor; //debug時(shí)發(fā)現(xiàn)此處會(huì)調(diào)用工廠方法 return ma.invoke(obj, args); } public static FactoryMethodBean getInstance(){ return new FactoryMethodBean(); }
2、使用帶參構(gòu)造函數(shù)初始化,無(wú)參構(gòu)造函數(shù)更簡(jiǎn)單,因?yàn)椴恍枰ㄎ粯?gòu)造函數(shù),創(chuàng)建對(duì)象類似使用帶參構(gòu)造函數(shù)初始化,最終會(huì)調(diào)用到此處.
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) { //如果有需要覆蓋或者動(dòng)態(tài)替換的方法則使用CGLIB動(dòng)態(tài)代理,可以在創(chuàng)建代理的同時(shí)動(dòng)態(tài)將方法織如類中 if (beanDefinition.getMethodOverrides().isEmpty()) { //如果沒(méi)有直接調(diào)用反射來(lái)構(gòu)造實(shí)例對(duì)象 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); //調(diào)用反射進(jìn)行構(gòu)造對(duì)象 return ctor.newInstance(args); } }
附錄 1、FactoryBean的使用
public interface FactoryBean{ //核心方法,讓實(shí)現(xiàn)類實(shí)現(xiàn)的,返回由FactoryBean創(chuàng)建的bean實(shí)例 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; } }
當(dāng)調(diào)用getBean時(shí),Spring通過(guò)反射機(jī)制發(fā)現(xiàn)CarFactoryBean實(shí)現(xiàn)了FactoryBean接口,這時(shí)Spring容器就調(diào)用接口方法getObject() 返回Bean實(shí)例.如果希望獲取CarFactoryBean的實(shí)例,需要使用getBean(beanName)方法時(shí)在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的使用方法”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Spring中加載Bean的使用方法這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!