真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何理解SpringFramework與IOC依賴查找

這篇文章主要介紹“如何理解SpringFramework與IOC依賴查找”,在日常操作中,相信很多人在如何理解SpringFramework與IOC依賴查找問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”如何理解SpringFramework與IOC依賴查找”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

定襄ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!

1. 談?wù)凷pringFramework / 說(shuō)說(shuō)你理解的SpringFramework

SpringFramework 是一個(gè)開(kāi)源的、松耦合的、分層的、可配置的一站式企業(yè)級(jí) Java 開(kāi)發(fā)框架,它的核心是 IOC 與 AOP  ,它可以更容易的構(gòu)建出企業(yè)級(jí) Java 應(yīng)用,并且它可以根據(jù)應(yīng)用開(kāi)發(fā)的組件需要,整合對(duì)應(yīng)的技術(shù)。

松耦合的: 為了描述IOC和AOP, 可能會(huì)延伸出IOC松耦合相關(guān)內(nèi)容 可配置: 給后面的SpringBoot(約定大于配置)做鋪墊 IOC 與 AOP:  Inverse of Control 控制反轉(zhuǎn)、Aspect Oriented Programming 面向切面編程

2. 為何使用SpringFramework

可通過(guò)如下幾點(diǎn)進(jìn)行描述:

IOC 實(shí)現(xiàn)了組件之間的解耦

AOP 切面編程將應(yīng)用業(yè)務(wù)做統(tǒng)一或特定的功能增強(qiáng), 可實(shí)現(xiàn)應(yīng)用業(yè)務(wù)與增強(qiáng)邏輯的解耦

容器管理應(yīng)用中使用的Bean、托管Bean的生命周期、事件與監(jiān)聽(tīng)的驅(qū)動(dòng)機(jī)制

Web、事務(wù)控制、測(cè)試、與其他技術(shù)的整合

3. SpringFramework包含哪些模塊?

  • beans、core、context、expression 【核心包】

  • aop 【切面編程】

  • jdbc 【整合 jdbc 】

  • orm 【整合 ORM 框架】

  • tx 【事務(wù)控制】

  • web 【 Web 層技術(shù)】

  • test 【整合測(cè)試】

  • ......

4. 依賴查找與依賴注入的對(duì)比

如何理解SpringFramework與IOC依賴查找

5. BeanFactory與ApplicationContext的對(duì)比

BeanFactory 接口提供了一個(gè)抽象的配置和對(duì)象的管理機(jī)制,

ApplicationContext 是 BeanFactory 的子接口,它簡(jiǎn)化了與 AOP 的整合、消息機(jī)制、事件機(jī)制,以及對(duì) Web 環(huán)境的擴(kuò)展(  WebApplicationContext 等)

ApplicationContext 主要擴(kuò)展了以下功能:

  • AOP 的支持( AnnotationAwareAspectJAutoProxyCreator 作用于 Bean 的初始化之后 )

  • 配置元信息( BeanDefinition 、Environment 、注解等 )

  • 資源管理( Resource 抽象 )

  • 事件驅(qū)動(dòng)機(jī)制( ApplicationEvent 、ApplicationListener )

  • 消息與國(guó)際化( LocaleResolver )

  • Environment 抽象( SpringFramework 3.1 以后)

2.  SpringFramework發(fā)展史

在Spring技術(shù)之前,J2EE興起,當(dāng)時(shí)的J2EE學(xué)習(xí)成本極高,開(kāi)發(fā)速度慢,開(kāi)發(fā)出來(lái)的程序性能消耗也高,已經(jīng)跟不上當(dāng)時(shí)應(yīng)用程序的需要。在2002  年,Rod Johnson寫(xiě)了一本書(shū)名為《Expert One-on-One J2EE design and development》 ,書(shū)中對(duì)當(dāng)時(shí)現(xiàn)有的  J2EE 應(yīng)用的架構(gòu)和EJB框架存在的臃腫、低效等問(wèn)題提出了質(zhì)疑,并且積極尋找和探索解決方案。

基于普通Java類和依賴注入的思想提出了更為簡(jiǎn)單的解決方案,這便是Spring框架核心思想的萌芽

過(guò)了 2 年,2004 年 SpringFramework 1.0.0 橫空出世,隨后 Rod Johnson 又寫(xiě)了一本書(shū)**《Expert  one-on-one J2EE Development without EJB》**,當(dāng)時(shí)在 J2EE  開(kāi)發(fā)界引起了巨大轟動(dòng),這本書(shū)中直接告訴開(kāi)發(fā)者完全可以不使用 EJB 開(kāi)發(fā) J2EE 應(yīng)用,而是可以換用一種更輕量級(jí)、更簡(jiǎn)單的框架來(lái)代替,那就是  SpringFramework 。

那時(shí)在開(kāi)發(fā)界是種種的質(zhì)疑,大概是這樣的,納尼? 質(zhì)疑IBM諸多大佬的設(shè)計(jì)精華,這個(gè)是什么人?為何如此囂張? 而后  還是被一些開(kāi)發(fā)者嘗試使用了,使用后發(fā)現(xiàn)確實(shí)要比EJB好用,不那么臃腫,性能也有所改善,提供的一些特性也優(yōu)于EJB,于是就慢慢轉(zhuǎn)投SpringFramework

下面展示下SpringFramework重要版本的更新時(shí)間及主要特性

如何理解SpringFramework與IOC依賴查找

3. IOC依賴查找

基礎(chǔ)框架搭建

1.創(chuàng)建Maven模塊,這里以ioc-learning為例

2.引入依賴

     org.springframework     spring-context     5.2.8.RELEASE 

3.創(chuàng)建配置文件 ioc-learning-dl.xml

            

4.聲明普通類Person.java

public class Person { }

5.ioc-learning-dl.xml配置文件加入Persion的聲明

6.創(chuàng)建啟動(dòng)類

public class DlApplication {     public static void main(String[] args) {         // 讀取配置文件  使用接口 BeanFactory 接收          BeanFactory factory = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");         // 通過(guò)配置文件中聲明的 id 進(jìn)行對(duì)象的獲取         Person person = (Person) factory.getBean("person");         System.out.println(person);     } }

7.運(yùn)行打印

com.huodd.bean.Person@57baeedf

成功打印出 Person 的全限定類名 + 內(nèi)存地址,證明編寫(xiě)成功。

3.1 byName 名稱查找

上述基礎(chǔ)框架中的步驟6

核心代碼

Person person = (Person) factory.getBean("person");

3.2 byType 類型查找

1. 普通類

1.修改配置文件 ioc-learning-dl.xml 將person的聲明中id屬性去掉

2.修改啟動(dòng)類

public static void main(String[] args) {         BeanFactory factory = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml"); //        Person person = (Person) factory.getBean("person");         Person person = factory.getBean(Person.class);         System.out.println(person);     }

getBean方法參數(shù)中直接傳入Class類型 返回值也無(wú)需再進(jìn)行強(qiáng)轉(zhuǎn)

3.運(yùn)行main方法 打印如下

com.huodd.bean.Person@61862a7f

2. 接口

1.創(chuàng)建接口demoDao 以及 實(shí)現(xiàn)類 DemoDaoImpl

public interface DemoDao {     List findAll(); }  public class DemoDaoImpl implements DemoDao{     @Override     public List findAll() {         return Arrays.asList("user1", "user2", "user3");     } }

2.修改配置文件 ioc-learning-dl.xml 加入 DemoDaoImpl的聲明

3.修改啟動(dòng)類

public static void main(String[] args) {        BeanFactory factory = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");        DemoDao demoDao = factory.getBean(DemoDaoImpl.class);        System.out.println(demoDao);        System.out.println(demoDao.findAll());    }

4.運(yùn)行main方法 打印結(jié)果如下

com.huodd.dao.DemoDaoImpl@7334aada [user1, user2, user3]

由此可見(jiàn) DemoDaoImpl 注入成功 并且BeanFactory可以根據(jù)接口類型找到對(duì)應(yīng)的實(shí)現(xiàn)類

3.3 高級(jí)查找

ofType 根據(jù)類型查找多個(gè)

如果一個(gè)接口有多個(gè)實(shí)現(xiàn)類,如何一次性的把所有的實(shí)現(xiàn)類都取出來(lái)呢? 前面用到的getBean方法顯然無(wú)法滿足 需使用到ofType方法

1.繼上面的代碼 創(chuàng)建2個(gè)DemoDao的實(shí)現(xiàn)類 如下

public class DemoMySQLDaoImpl implements DemoDao {     @Override     public List findAll() {         return Arrays.asList("mysql_user1", "mysql_user2", "mysql_user3");     } } public class DemoOracleDaoImpl implements DemoDao {     @Override     public List findAll() {         return Arrays.asList("oracle_user1", "oracle_user2", "oracle_user3");     } }

2.修改配置文件 ioc-learning-dl.xml 加入新建的兩個(gè)實(shí)現(xiàn)類的聲明

 

3.修改啟動(dòng)類

public static void main(String[] args) {         ApplicationContext ctx = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");         Map beans = ctx.getBeansOfType(DemoDao.class);         beans.forEach((beanName, bean) -> {             System.out.println(beanName + " : " + bean.toString());         });      }

運(yùn)行main方法 打印結(jié)果如下

com.huodd.dao.impl.DemoMysqlDaoImpl#0 : [mysql_user1, mysql_user2, mysql_user3] com.huodd.dao.impl.DemoOracleDaoImpl#0 : [oracle_user1, oracle_user2, oracle_user3]

細(xì)心的小伙伴可能會(huì)發(fā)現(xiàn) 為何這里讀取配置文件的返回值使用的是ApplicationContext 而不使用BeanFactory

ApplicationContext 也是一個(gè)接口,通過(guò)IDEA的diagram查看類的繼承鏈,可以看到該接口繼承了BeanFactory

官方文章中有這樣的解釋:

org.springframework.beans 和 org.springframework.context 包是 SpringFramework 的  IOC 容器的基礎(chǔ)。BeanFactory 接口提供了一種高級(jí)配置機(jī)制,能夠管理任何類型的對(duì)象。ApplicationContext 是 BeanFactory  的子接口。它增加了:

  • 與 SpringFramework 的 AOP 功能輕松集成

  • 消息資源處理(用于國(guó)際化)

  • 事件發(fā)布

  • 應(yīng)用層特定的上下文,例如 Web 應(yīng)用程序中使用的 WebApplicationContext

如此說(shuō)來(lái) ApplicationContext 包含了 **BeanFactory 的所有功能,**并且還擴(kuò)展了更多的特性

其實(shí)對(duì)于我們目前的最主要原因是BeanFactory 中木有g(shù)etBeansOfType()這個(gè)方法~~~

withAnnotation 根據(jù)注解查找

IOC 容器還可以根據(jù)類上標(biāo)注的注解來(lái)查找對(duì)應(yīng)的 Bean

1.創(chuàng)建一個(gè)注解類

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface animal { }

2.創(chuàng)建幾個(gè)bean對(duì)象

@Animal public class Dog { }  @Animal public class Cat { }  public class Xiaoming { }

其中只有Xiaoming這個(gè)類沒(méi)有添加@Animal注解

3.修改XML配置文件,添加如下三個(gè)聲明

  

4.修改啟動(dòng)類

public class DlApplication {     public static void main(String[] args) {         ApplicationContext ctx = new ClassPathXmlApplicationContext("dl/ioc-learning-dl.xml");         Map beans = ctx.getBeansWithAnnotation(Animal.class);         beans.forEach((beanName, bean) -> {             System.out.println(beanName + " : " + bean);         });     } }

5.運(yùn)行main方法 打印結(jié)果如下

dog : com.huodd.bean.Dog@313ac989 cat : com.huodd.bean.Cat@4562e04d

延遲查找

對(duì)于一些特殊場(chǎng)景,需要依賴容器中某些特定的bean 但是當(dāng)他們不存在時(shí)如何使用默認(rèn)/或者缺省策略來(lái)處理邏輯呢?

這里我們先把xml配置文件中的 Dog 的聲明暫時(shí)刪掉

這樣我們?cè)讷@取dog的時(shí)候ctx.getBean(Dog.class)就會(huì)報(bào)錯(cuò)

NoSuchBeanDefinitionException

1.現(xiàn)有方案啟用缺省策略

Dog dog; try {     dog = ctx.getBean(Dog.class); } catch (NoSuchBeanDefinitionException e) {     // 找不到Dog時(shí)手動(dòng)創(chuàng)建     dog = new Dog(); } System.out.println(dog);

這里我們把業(yè)務(wù)代碼寫(xiě)在了catch代碼塊中,不夠優(yōu)雅,性能也有待改善,而且如果后期每個(gè)bean都這樣處理,代碼量巨大

2.改造下 獲取之前檢查

Dog dog = ctx.containsBean("dog") ? (Dog) ctx.getBean("dog") : new Dog();

這里使用到了ApplicationContext中的方法 containsBean 用于檢查容器中是否有指定的bean

該方法看似已經(jīng)沒(méi)有問(wèn)題了,但是要考慮到該方法傳遞的參數(shù)只能傳遞bean的id 不能按照bean的類型去查找  如果bean的名字是其他的呢,工作量還是巨大的

3.使用延遲查找

該機(jī)制的大概思路為 當(dāng)我們想要獲取一個(gè)Bean的時(shí)候,先返回給我們一個(gè)包裝類,等到我們真正去使用的時(shí)候再去“拆包”檢查里面到底有沒(méi)有該Bean對(duì)象

使用方法如下

ObjectProvider dogProvider = ctx.getBeanProvider(Dog.class);

上面代碼可以看到 就是按照前面的思路進(jìn)行處理的,返回了一個(gè)“包裝”給我們,當(dāng)我們使用的時(shí)候直接調(diào)用getObject方法

但如果 容器中沒(méi)有該Bean 還是會(huì)報(bào) NoSuchBeanDefinitionException  ,下面會(huì)介紹下ObjectProvider提供的其他方法

  • getIfAvailable()該方法可以在找不到Bean的時(shí)候返回null 而不拋出異常

可以使用如下方法實(shí)現(xiàn)

Dog dog = dogProvider.getIfAvailable(Dog::new);
  • ifAvailable()該方法是在取到Bean后馬上或者間歇的使用

代碼如下

dogProvider.ifAvailable(dog -> System.out.println(dog)); // 或者使用方法引用

到此,關(guān)于“如何理解SpringFramework與IOC依賴查找”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!


網(wǎng)頁(yè)名稱:如何理解SpringFramework與IOC依賴查找
分享地址:http://weahome.cn/article/pgcdog.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部