本篇內(nèi)容介紹了“Spring-IOC的高級特性有哪些”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)公司"三網(wǎng)合一"的企業(yè)建站思路。企業(yè)可建設(shè)擁有電腦版、微信版、手機版的企業(yè)網(wǎng)站。實現(xiàn)跨屏營銷,產(chǎn)品發(fā)布一步更新,電腦網(wǎng)絡(luò)+移動網(wǎng)絡(luò)一網(wǎng)打盡,滿足企業(yè)的營銷需求!創(chuàng)新互聯(lián)公司具備承接各種類型的成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計項目的能力。經(jīng)過10年的努力的開拓,為不同行業(yè)的企事業(yè)單位提供了優(yōu)質(zhì)的服務(wù),并獲得了客戶的一致好評。
Bean的延遲加載(延遲創(chuàng)建)
ApplicationContext 容器的默認行為是在啟動服務(wù)器時將所有 singleton bean 提前進行實例化。提前實例化意味著作為初始化過程的?部分,ApplicationContext 實例會創(chuàng)建并配置所有的singleton bean。
比如:
該bean默認的設(shè)置為:
lazy-init="false",立即加載,表示在spring啟動時,立刻進行實例化。如果不想讓?個singleton bean 在 ApplicationContext實現(xiàn)初始化時被提前實例化,那么可以將bean設(shè)置為延遲實例化。
設(shè)置 lazy-init 為 true 的 bean 將不會在 ApplicationContext 啟動時提前被實例化,而是第?次向容器通過 getBean 索取 bean 時實例化的。
如果?個設(shè)置了立即加載的 bean1,引用了?個延遲加載的 bean2 ,那么 bean1 在容器啟動時被實例化,而 bean2 由于被 bean1 引用,所以也被實例化,這種情況也符合延時加載的 bean 在第?次調(diào)用時才被實例化的規(guī)則。
也可以在容器層次中通過在 元素上使用 "default-lazy-init" 屬性來控制延時初始化。如下面配置:
如果?個 bean 的 scope 屬性為 scope="pototype" 時,即使設(shè)置了 lazy-init="false",容器啟動時也不
會實例化bean,而是調(diào)用 getBean 方法實例化的。
應(yīng)用場景
(1)開啟延遲加載?定程度提高容器啟動和運轉(zhuǎn)性能
(2)對于不常使用的 Bean 設(shè)置延遲加載,這樣偶爾使用的時候再加載,不必要從?開始該 Bean 就占用資源
BeanFactory接口是容器的頂級接口,定義了容器的?些基礎(chǔ)行為,負責(zé)生產(chǎn)和管理Bean的?個工廠,具體使用它下面的子接口類型,比如ApplicationContext;此處我們重點分析FactoryBean
Spring中Bean有兩種,?種是普通Bean,?種是工廠Bean(FactoryBean),F(xiàn)actoryBean可以生成某?個類型的Bean實例(返回給我們),也就是說我們可以借助于它自定義Bean的創(chuàng)建過程。
Bean創(chuàng)建的三種方式中的靜態(tài)方法和實例化方法和FactoryBean作用類似,F(xiàn)actoryBean使用較多,尤其在Spring框架?些組件中會使用,還有其他框架和Spring框架整合時使用
// 可以讓我們?定義Bean的創(chuàng)建過程(完成復(fù)雜Bean的定義) public interface FactoryBean{ @Nullable // 返回FactoryBean創(chuàng)建的Bean實例,如果isSingleton返回true,則該實例會放到Spring容器 的單例對象緩存池中Map T getObject() throws Exception; @Nullable // 返回FactoryBean創(chuàng)建的Bean類型 Class> getObjectType(); // 返回作?域是否單例 default boolean isSingleton() { return true; } }
Company類
package com.bxc.edu.pojo; /** * @author bixc */ public class Company { private String name; private String address; private int scale; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getScale() { return scale; } public void setScale(int scale) { this.scale = scale; } @Override public String toString() { return "Company{" + "name='" + name + '\'' + ", address='" + address + '\'' + ", scale=" + scale + '}'; } }
CompanyFactoryBean類
package com.bxc.edu.factory; import com.bxc.edu.pojo.Company; import org.springframework.beans.factory.FactoryBean; /** * @author bixc */ public class CompanyFactoryBean implements FactoryBean{ private String companyInfo; // 公司名稱,地址,規(guī)模 public void setCompanyInfo(String companyInfo) { this.companyInfo = companyInfo; } @Override public Company getObject() throws Exception { // 模擬創(chuàng)建復(fù)雜對象Company Company company = new Company(); String[] strings = companyInfo.split(","); company.setName(strings[0]); company.setAddress(strings[1]); company.setScale(Integer.parseInt(strings[2])); return company; } @Override public Class> getObjectType() { return Company.class; } @Override public boolean isSingleton() { return true; } }
xml配置
測試,獲取FactoryBean產(chǎn)生的對象
Object companyBean = applicationContext.getBean("companyBean"); System.out.println("bean:" + companyBean); // 結(jié)果如下 bean:Company{name='阿里', address='中關(guān)村', scale=500}
測試,獲取FactoryBean,需要在id之前添加“&”
Object companyBean = applicationContext.getBean("&companyBean"); System.out.println("bean:" + companyBean); // 結(jié)果如下 bean:com.bxc.edu.factory.CompanyFactoryBean@53f6fd09
Spring提供了兩種后處理bean的擴展接口,分別為 BeanPostProcessor 和BeanFactoryPostProcessor,兩者在使用上是有所區(qū)別的。
工廠初始化(BeanFactory)—> Bean對象
在BeanFactory初始化之后可以使用BeanFactoryPostProcessor進行后置處理做?些事情
在Bean對象實例化(并不是Bean的整個生命周期完成)之后可以使用BeanPostProcessor進行后置處理做?些事情
注意:對象不?定是springbean,而springbean一定是個對象
BeanPostProcessor
BeanPostProcessor是針對Bean級別的處理,可以針對某個具體的Bean.
該接口提供了兩個方法,分別在Bean的初始化方法前和初始化方法后執(zhí)行,具體這個初始化方法指的是什么方法,類似我們在定義bean時,定義了init-method所指定的方法
定義?個類實現(xiàn)了BeanPostProcessor,默認是會對整個Spring容器中所有的bean進行處理。如果要對具體的某個bean處理,可以通過方法參數(shù)判斷,兩個類型參數(shù)分別為Object和String,第?個參
數(shù)是每個bean的實例,第?個參數(shù)是每個bean的name或者id屬性的值。所以我們可以通過第?個參數(shù),來判斷我們將要處理的具體的bean。
注意:處理是發(fā)生在Spring容器的實例化和依賴注?之后。
BeanFactoryPostProcessor
BeanFactory級別的處理,是針對整個Bean的工廠進行處理,典型應(yīng)用:PropertyPlaceholderConfigurer
此接口只提供了?個方法,方法參數(shù)為ConfigurableListableBeanFactory,該參數(shù)類型定義了?些方法
其中有個方法名為getBeanDefinition的方法,我們可以根據(jù)此方法,找到我們定義bean 的BeanDefinition對象。然后我們可以對定義的屬性進行修改,以下是BeanDefinition中的方法
方法名字類似我們bean標簽的屬性,setBeanClassName對應(yīng)bean標簽中的class屬性,所以當我們拿到BeanDefinition對象時,我們可以手動修改bean標簽中所定義的屬性值。
BeanDefinition對象:我們在 XML 中定義的 bean標簽,Spring 解析 bean 標簽成為?個 JavaBean,這個JavaBean 就是 BeanDefinition
注意:調(diào)用 BeanFactoryPostProcessor 方法時,這時候bean還沒有實例化,此時 bean 剛被解析成BeanDefinition對象
“Spring-IOC的高級特性有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!