<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          spring專題系列之IOC的理解和分析

          共 6449字,需瀏覽 13分鐘

           ·

          2021-05-10 09:35

          根據(jù)時(shí)間安排,今天主要是對(duì)spring中IOC的理解。對(duì)于IOC的理解可以從以下幾個(gè)角度去分析。

          • 什么是IOC?如何使用案例來(lái)理解?
          • IOC有哪幾種實(shí)現(xiàn)方式?
          • IOC的底層實(shí)現(xiàn)過(guò)程是什么?

          根據(jù)這幾個(gè)角度,開始今天的故事,

          1 什么是IOC?

          對(duì)于IOC的理解,主要是停留在概念和幾種注入的方式上,雖然知道其生命周期,但是對(duì)整個(gè)bean管理的宏觀角度,理解的不夠深刻。

          IOC:**控制反轉(zhuǎn)(Inversion of Control)容器,**是一種設(shè)計(jì)思想。意味著將你設(shè)計(jì)好的對(duì)象交給容器控制。

          1.1 什么是依賴注入

          這個(gè)概念的理解,我準(zhǔn)備使用一個(gè)案例來(lái)表示。如果a類中包含了b類,就說(shuō)明a類對(duì)b類產(chǎn)生了依賴。如一個(gè)人需要車,這就說(shuō)人對(duì)車產(chǎn)生了依賴。

          class User
            Car car; 
            public User()
              car=new Car(); 
            } 
          }

          上面這個(gè)案例,可以看到,在User類中,包含了Car類,也就說(shuō)User類對(duì)Car類產(chǎn)生了依賴。

          按照傳統(tǒng)的方式,User類如果想要使用Car基本上就是在內(nèi)部new一個(gè)新對(duì)象即可。但是這樣做缺點(diǎn)很大,new的方式也就意味著User和Car產(chǎn)生了緊耦合。不利于大規(guī)模使用。于是使用了另外一種方式可以代替。那就是什么時(shí)候用到Car,從外部直接傳遞過(guò)來(lái)就好。這樣的話,耦合性就大大降低了。再看下面這種形式是不是就好很多了。

          class User
            Car car; 
            public User(Car car)
              this.car=car; 
            } 
          }

          像這樣的方式就是依賴注入,也就是把依賴Car注入到了User中。

          1.2 什么是控制反轉(zhuǎn)

          有了上面依賴注入的概念,再立即控制反轉(zhuǎn)就比較簡(jiǎn)單了。

          • 誰(shuí)控制誰(shuí):傳統(tǒng)方式User是在內(nèi)部new,現(xiàn)在我們通過(guò)依賴注入的方式注入依賴對(duì)象Car。現(xiàn)在spring出現(xiàn)了,發(fā)明了IOC,IOC里面有一個(gè)容器,這些依賴對(duì)象全部交給容器去管理。也就是說(shuō)這些依賴對(duì)象的控制權(quán)交給了容器。

          • 如何反轉(zhuǎn):傳統(tǒng)方式User是主動(dòng)去new,這種方式是正轉(zhuǎn)。反轉(zhuǎn)是由容器來(lái)幫忙創(chuàng)建及注入依賴對(duì)象;

          2 依賴注入的幾種形式

          目前主要有五種注入方式:SET注入,構(gòu)造器注入,靜態(tài)工廠,實(shí)例工廠。

          本文直接使用網(wǎng)上的基本案例來(lái)實(shí)現(xiàn)。比如UserService依賴UserDao。先把UserDao定義好了,接下來(lái)看如何實(shí)現(xiàn)注入的。

          public class UserDao {
           public String userLogin() {
            return "userLogin()方法";
           }
          }

          下面看幾種依賴注入的幾種實(shí)現(xiàn)方式。

          2.1 set注入

          第一步:XML配置

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd"
          >

           <bean id="userDao" class="com.xxx.demo.UserDao"></bean>
           <!-- setter注入 -->
           <bean id="userService" class="com.xxx.demo.UserService">
                  <!--ref是對(duì)于外部bean對(duì)象引用,與被引用的bean對(duì)象的id保持一致-->
            <property name="userDao" ref="userDao"></property>
           </bean>
          </beans>

          第二步:set方式注入

          public class UserService {
              //一定要提供屬性的setter方法
           private UserDao userDao;
           public void userlogin() {
            String res=userDao.userLogin();
            System.out.println(res);
           }
           public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
           }
          }

          這種方式簡(jiǎn)單易操作。

          2.2 構(gòu)造器注入

          第一步:XML配置

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd"
          >

           <bean id="userDao" class="com.xxx.demo.UserDao"></bean>
           <!-- 構(gòu)造器注入 -->
           <bean id="userServiceV2" class="com.xxx.demo.UserServiceV2">
            <constructor-arg index="0" ref="userDao"></constructor-arg>
            <constructor-arg index="1" value="印度三哥"></constructor-arg>
           </bean>
          </beans>

          第二步:構(gòu)造器注入

          public class UserServiceV2 {
           private UserDao userDao;
           private String name;
           public void userlogin() {
            String res=userDao.userLogin();
            System.out.println(res);
            System.out.println(name);
           }
           public UserServiceV2(UserDao userDao,String name) {
            super();
            this.userDao = userDao;
            this.name = name;
           }
          }

          2.3 靜態(tài)工廠注入

          第一步:XML配置

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd"
          >

           <!-- 靜態(tài)工廠注入 -->
           <bean id="userDao01" class="com.xxx.demo.StaticFactory" factory-method="createuserDao"></bean>
           <bean id="userService01" class="com.xxx.demo.UserService">
            <property name="userDao" ref="userDao01"></property>
           </bean>
          </beans>

          第二步:定義靜態(tài)工廠

          public class StaticFactory {
           public static UserDao createuserDao(){
            return new UserDao();
           }
          }

          第三部:靜態(tài)工廠注入

          public class UserService {
           private UserDao userDao;
           public void userlogin() {
            String res=userDao.userLogin();
            System.out.println(res);
           }
           public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
           }
          }

          2.4 實(shí)例化工廠

          第一步:XML配置

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd"
          >

           <!-- 實(shí)例化工廠 -->
           <bean id="instanceFactory" class="com.xxx.demo.InstanceFactory"></bean>
           <bean id="userDao3" factory-bean="instanceFactory" factory-method="createUserDao"></bean>
           <bean id="userService02" class="com.xxx.demo.UserService">
            <property name="userDao" ref="userDao3"></property>
           </bean>
          </beans>

          第二步:工廠注入

          public class InstanceFactory {
           public UserDao createUserDao(){
            return new UserDao();
           }
          }

          以上就是幾種常見的注入方式。在開發(fā)中比較常用。知道了IOC的概念和幾種實(shí)現(xiàn)方式之后,下面主要探討IOC的底層實(shí)現(xiàn)原理。

          3 IOC底層實(shí)現(xiàn)過(guò)程

          以上的幾種注入方式,可能有個(gè)疑問(wèn),那就是bean是如何從xml,再到注入類中的呢?看下面這張圖

          Spring IOC容器初始化的核心過(guò)程主要有四個(gè)步驟(還有一些如:后置加載器,國(guó)際化,事件廣播器等一些過(guò)程不展開):

          1. Bean定義的定位,Bean 可能定義在XML中,或者一個(gè)注解,或者其他形式。這些都被用Resource來(lái)定位,讀取Resource獲取BeanDefinition 注冊(cè)到 Bean定義注冊(cè)表中。
          2. 第一次向容器getBean操作會(huì)觸發(fā)Bean的創(chuàng)建過(guò)程,實(shí)列化一個(gè)Bean時(shí) ,根據(jù)BeanDefinition中類信息等實(shí)列化Bean。
          3. 將實(shí)列化的Bean放到單列Bean緩存內(nèi)。
          4. 此后再次獲取向容器getBean就會(huì)從緩存中獲取。

          這張圖是核心的過(guò)程。這個(gè)過(guò)程是已經(jīng)簡(jiǎn)化了,具體的實(shí)現(xiàn)方式要設(shè)計(jì)到bean的生命周期的管理。安排到下一章節(jié)了。spring的核心內(nèi)容就是aop和ioc,知道了這倆是如何實(shí)現(xiàn)的之后,就是核心bean管理的核心實(shí)現(xiàn),最后對(duì)配置文件進(jìn)行介紹。


          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  翔田千里成人AV片 | 三区视频在线播放 | 国产一区视频在线 | 这里只有99精品 | 蘑菇视频logo红色 |