<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Spring系列__02IOC模塊簡介

      Spring的兩大核心功能就是IoC和AOP,這篇文章主要介紹IoC。
      簡單來說,在面向對象思想下,A類中有一個B類的屬性, 那么我們在創建A類時往往需要同時創建一個B類的對象,以便A類對其進行調用。但是,這樣的后果便是,A類和B類的耦合度過高。而所謂的IoC(控制反轉),其核心是DI,旨在提供一種更簡單的機制來設置組件依賴項(通常稱為對象的協作者),并在整個生命周期中管理這些依賴項。IoC通常可以分為兩種子類型:依賴注入和依賴查找。

      依賴注入和依賴查找的介紹

      依賴查找是一種更傳統的方法,有兩種類型:

      • 依賴拉取(dependency pull,DL)
        在依賴拉取中,根據需要從注冊表中提取依賴項,在IoC中,往往是使用JNDI查找來獲取依賴項。
      • 上下文依賴查找(contextualized dependency lookup, ontextualized dependency lookup, CDL)
        上下文查找和依賴拉取有些相似,但是不同之處就是,查找是針對管理資源的容器執行的,而不是來自某個中央注冊表。
        當容器準備將依賴傳遞給組件時,會依次調用每個組件的performLookup()方法,然后,組件可以使用Contaioner接口來查找所需要的依賴項。

      依賴注入是目前被廣泛采用的新方案,也有兩種常見的風格

      • 構造函數
        當在組件的構造函數中提供依賴項的時候,就會發生構造函數依賴注入。
        首先,組件聲明一個或者一組構造函數,并將其作為依賴項作為參數;
        然后在組件實例化的時候有IoC容器將依賴項傳遞給組件。如下代碼所演示:
      public class ConstuctorInjecttion {
          private Dependency dependency;
          public ConstructorInjection(Dependency dependency) {
              this.dependency = dependency;
          }
      }
      
      構造函數注入屬于強制性的依賴注入,如果沒有依賴項的時候,就不能創建對象;因此,必須有依賴項。
      
      • setter方法注入
        在setter依賴注入中,IoC容器通過使用JavaBean樣式的setter方法注入組件的依賴項。組件的setter方法公開了IOC容器可以管理的依賴項。示例如下:
      public class SetterInjection {
          private Dependency dependency;
          
          public void setDependency(Dependency dependency) {
              this.dependency = dependency;
          } 
      }
      
      Setter注入屬于可選依賴注入,可以在沒有依賴項的情況下創建對象(調用默認的無參構造器), 然后通過調用setter方法來提供依賴項。
      

      查找和注入的比較總結

      - 查找:
      1.依賴拉取代碼必須主動獲得對注冊表的依賴選項;
      2.難以獨立于容器進行測試。
      - 注入:
      1.對代碼沒有任何影響;
      2.可以獨立于容器進行測試。
      3.開發更加自由。
      

      setter注入和構造器注入比較總結

      - 構造器注入:當對依賴項的依賴關系為強制依賴的時候,推薦使用這種方式,通過調用對應的帶參數構造器來完成依賴的注入。
      - setter方法注入:最簡單的注入方式。當對依賴項的依賴關系為可選的時候,推薦使用這種方式。通過反射調用無參構造器來實例后,再調用對應的setter方法。這種方式的最大的好處就是:侵入性最小。
      

      Spring中的控制反轉

      對于控制反轉,Spring的實現核心是基于依賴注入,而Spring的依賴注入的核心是BeanFactory接口。BeanFactory負責管理組件,包括依賴項以及他們的生命周期。但是,在實際的使用中,Beanfactory的使用并不是很多,通常使用其擴展:ApplicationContext,其是BeanFactory的子接口。后面會有詳細介紹。
      

      1.bean的配置

      1.配置形式:

      有三種配置形式,但是通常說兩種:xml文件和注解,(有些書籍上說第三種是自動裝配)。本文中主要介紹xml形式進行bean的配置。

      2.配置方式:

      bean的配置方式有三種:

      • 通過反射的方式進行配置:
        該方式會通過反射機制調用無參構造器來創建對象實例,但是,若是沒有無參構造器,則會拋出異常。
      <!--
              bean的配置方式1:通過全類名方式(反射)
              id:IOC容器中唯一存在,若不指定會默認使用全類名
          -->
          <bean id="car" class="com.spring.demo.bean.Car">
       <!--
      
      • 通過工廠方法(靜態工廠、實例工廠):
        該方法會運用了工廠模式的思想,通過調用靜態工廠、實例工廠的方法來創建bean的實例。
      <!--
             bean的配置方式2:通過靜態工廠方法
             id 屬性:指定 bean 的 id,用于從容器中獲取
             class 屬性:指定靜態工廠的全限定類名
             factory-method 屬性:指定生產對象的靜態方法
          -->
              <bean id="carByFactory" class="com.spring.demo.bean.StaticFactory"
                    factory-method="getCarBean">
      
              </bean>
      
      
          <!--
               bean的配置方式2:通過實例工廠方法
              此種方式是:先把工廠的創建交給 spring 來管理,然后在使用工廠的 bean 來調用里面的方法
              factory-bean 屬性:用于指定實例工廠 bean 的 id。
              factory-method 屬性:用于指定實例工廠中創建對象的方法。
        -->
              <bean id="instanceFactory" class="com.spring.demo.bean.InstanceFactory"></bean>
              <bean id="carByInstance" class="com.spring.demo.bean.Car" factory-bean="instanceFactory"
                    factory-method="getCarByInstance">
                  <property name="brand" value="大眾"/>
              </bean>
      
      • 通過Spring提供的FactoryBean進行配置(使用較少,暫不介紹)。

      3.依賴注入的方式:屬性注入、構造器注入

      依賴注入: Dependency Injection。 它是 spring 框架核心 ioc 的具體實現。我們的程序在編寫時, 通過控制反轉, 把對象的創建交給了 spring,但是代碼中不可能出現沒有依賴的情況。IoC 解耦只是降低他們的依賴關系,但不會消除。 例如:我們的業務層仍會調用持久層的方法。那這種業務層和持久層的依賴關系, 在使用 Spring 之后, 就讓 Spring 來維護了。簡單的說,就是坐等框架把持久層對象傳入業務層,而不用我們自己去獲取。
      依賴注入的方式主要有兩種:

      • 屬性注入就是調用setter方法進行屬性注入,;
      • 構造器注入方式是調用重載的帶參構造器。
        說到這里,可以來一些代碼了:
      <!--
              依賴注入方式1:屬性注入,屬性注入是通過setter方法注入bean的屬性值或者依賴的對象。
              也是實際應用中最常用的方式。
              name指定屬性值,value或者value節點指定屬性值,ref指定依賴的對象
          -->
              <property name="company" value="大眾"/>
              <property name="brand" value="寶來"/>
              <property name="price" value="200000.00"/>
              <property name="maxSpeed" value="200"/>
          </bean>
      
          <!--
             依賴注入方式2:構造器注入
             通過構造方法注入屬性,能夠保證bean在實例化后就能使用
             沒有name屬性,默認按照構造器的變量順序加載,也可以通過index或者type進行限制
             index:指定參數在構造函數參數列表的索引位置
             type:指定參數在構造函數中的數據類型
         -->
          <!--
             若一個 bean 有多個構造器, 如何通過構造器來為 bean 的屬性賦值
             可以根據 index 和 value 進行更加精確的定位. (了解)
             也可以通過name來具體制定屬性名進行綁定
             若字面值中包含特殊字符, 則可以使用 DCDATA 來進行賦值. (了解)
             使用構造器方式注入屬性值時,可以使用type或index來區別重載構造器
         -->
          <bean id="car1" class="com.spring.demo.bean.Car">
              <constructor-arg value="寶馬" type="java.lang.String"/>
              <constructor-arg value="mini" type="java.lang.String"/>
              <constructor-arg value="200000.00" type="double"/>
              <constructor-arg value="240" type="int"/>
          </bean>
          <!--
              依賴注入方式3:工廠方法注入
              因為這種方法比較少使用,這里只是寫一下注釋,沒有demo
           -->
      

      4.IOC容器BeanFactory和ApplicationContext簡介

      BeanFactory是Spirng框架的基礎設施,面向Spring本身;ApplicationContext是BeanFactory的子接口,面向Spring框架的應用者,其提供了更多的功能。
      ApplicationContext具有兩個只要的實現類:ClasspathXmlApplicationContext和FileSystemXmlApplicationContext;前者通過在類路徑下加載配置文件來完成bean的裝配,后者從文件系統下加載配置文件。項目結構如下所示:
      ![](https://img2018.cnblogs.com/blog/1632582/201908/1632582-20190806192700756-971547115.png

      BeanFactory 和 ApplicationContext 的區別:創建對象的時間點不一樣。

      • ApplicationContext:只要一讀取配置文件,默認情況下就會創建對象。
      • BeanFactory:什么使用什么時候創建對象。

      ApplicationContext 接口的實現類

      • ClassPathXmlApplicationContext:它是從類的根路徑下加載配置文件 推薦使用這種
      • FileSystemXmlApplicationContext:它是從磁盤路徑上加載配置文件,配置文件可以在磁盤的任意位置。
      • AnnotationConfigApplicationContext:當我們使用注解配置容器對象時,需要使用此類來創建 spring 容器。它用來讀取注解。
        在這里,則可以進行測試了:
      @Test
          public void teStetter() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-ioc.xml");
              Car car = (Car) context.getBean("car");
              System.out.println(car);
          }
      

      5.字面值

      字面值可以用value標簽或者value屬性進行注入。基本類型及其包裝類、String等都是采用字面值的方式進行注入。當具有特殊字符的時候,需要特殊處理:

      <!--
              value簡介:
                  基本類型及其包裝類、String都可以通過value標簽或者value屬性注入,
                  當字面值包含特殊字符的時候,可用<![CDATA[]]>包含
           -->
          <bean id="car2" class="com.spring.demo.bean.Car">
              <property name="company" value="大眾"/>
              <property name="brand">
                  <value><![CDATA[<DZ寶來>]]></value>
              </property>
              <property name="maxSpeed" value="200"/>
              <property name="price" value="200000.00"/>
          </bean>
      

      spring中某一屬性不進行顯式聲明時,其會采用默認值,當然你可以顯式的注入null:適應null標簽
      同時,spring支持級聯屬性的注入。

      6.引用其他bean

      當需要引用其他的bean時(A類引用B類),可以通過ref標簽或者ref屬性進行注入。其用法和value類似。泣別:value注入的是字面值,ref注入的是一個引用。當然,內部bean的注入也是這種方式。
      示例如下:

      <!--
              引入其他bean:
                  例如person有car屬性,需要引入,這是就不是使用value屬性了,
                  而是使用ref指定需要引入的bean
                  也可以聲明一個內部bean,此時內部bean就無需再指定id了,道理和內部類相似
          -->
          <bean id="person" class="com.spring.demo.bean.Person">
              <property name="name" value="麗麗"/>
              <property name="age" value="23"/>
              <property name="car" ref="car"/>
          </bean>
      
          <!-- innerBean -->
          <bean id="person1" class="com.spring.demo.bean.Person">
              <property name="name" value="麗麗"/>
              <property name="age" value="23"/>
              <property name="car">
                  <bean class="com.spring.demo.bean.Car">
                      <property name="brand" value="BMW"/>
                      <property name="company" value="BMW"/>
                      <property name="maxSpeed" value="233"/>
                      <property name="price" value="233333.33"/>
                  </bean>
              </property>
          </bean>
      

      7.集合屬性

      在Spring中可以通過xml標簽配置集合屬性:

      1.list和數組

      配置java.util.LIst和數組類型時,可以通過標簽來配置,list中的屬性可以使用value標簽或者ref標簽。
      可以使用utility scheme來單獨定義集合,這樣的好處就是方便其他bean進行引用。

      2.set

      set的情況和list相似,使用set標簽,用法和list標簽一樣。

      <!--
              集合屬性:
                  list標簽:數組和list數據使用這個標簽,
                  set標簽:set數據使用,使用方法同list標簽
          -->
          <bean id="stu" class="com.spring.demo.bean.Student">
              <property name="name" value="蘇大強"/>
              <property name="age" value="60"/>
              <property name="cars">
                  <list>
                      <ref bean="car"/>
                      <ref bean="car1"/>
                      <ref bean="car2"/>
                      <ref bean="car3"/>
                  </list>
              </property>
          </bean>
      
          <!--
              也可以單獨定義list,然后直接綁定
          -->
          <util:list id="carList">
              <ref bean="car"/>
              <ref bean="car1"/>
              <ref bean="car2"/>
              <ref bean="car3"/>
          </util:list>
      
          <bean id="stu1" class="com.spring.demo.bean.Student">
              <property name="name" value="蘇大強"/>
              <property name="age" value="60"/>
              <property name="cars" ref="carList"/>
          </bean>
      

      3.map和properties

      java.util.Map可以通過map標簽進行指定,map標簽中有多個entity子標簽,每個entity定義一對鍵值對。
      在entity中可以通過key屬性或者key標簽來指定鍵,同理可以使用value、ref、bean、null屬性或者標簽指定值。

      <!--
              map:
                  map的使用可list相似,使用entry標簽來保存每一對鍵值對,
                  同時可以使用key屬性或者key標簽來存儲key,
                  value值或value屬性綁定普通的字面值,ref綁定其他bean作為值
          -->
          <bean id="teacher" class="com.spring.demo.bean.Teacher">
              <property name="name" value="張莉"/>
              <property name="age" value="24"/>
              <property name="carMap">
                  <map>
                      <entry key="car" value-ref="car"/>
                      <entry key="car1" value-ref="car1"/>
                      <entry key="car2" value-ref="car2"/>
                      <entry key="car3" value-ref="car3"/>
                  </map>
              </property>
          </bean>
      

      props標簽用來定義java.util.Properties,該標簽有子標簽prop,具體使用方法與map一樣。

      8.p命名空間

      Spring2.5之后支持p命名空間,可以簡化xml配置,屬性與原來的配置一樣:

      <!--
              spring2.5之后,可以使用p命名空間來簡化屬性配置,需要在配置文件中引入p命名空間
             xmlns:p="http://www.springframework.org/schema/p"
          -->
          <bean id="car4" class="com.spring.demo.bean.Car" p:brand="寶馬" p:company="寶馬"
                p:price="2000000.00" p:maxSpeed="200"/>
      

      8.Java配置

      前面的例子都是通過xml文件進行bean的配置,現在來示范一下通過Java配置方式來配置。

      @Configuration   //該注解表示這個類是一個配置類,其作用相當于配置文件。
      public class CarConfigure {
          @Bean    //該注解表示會向容器中配置一個bean,其value屬性是設置bean的id,
                          //沒有的話默認使用方法名作為id,bean的類型就是返回值類型
          public Car carByAnnotation() {
              return new Car();
          }
      }
      

      9.autowire

      Spring的IOC容器可以通過自動裝配來配置bean,使用方式就是使用autowire屬性,有兩種模式:byName和byType。
      byName會在Spring容器中根據名字取尋找匹配的bean,沒有的話就無法完成裝配;
      byType會在Spring容器中按照類型來查找并進行bean的配置,但是當找到多個符合條件的類型的bean時會報異常,不過可以通過primary屬性或注解來制定bean的優先級,但是當你設置了多個同一類型的bean的primary屬性為true的時候失效;這個時候,可以借助@Qualifier注解來加以限制。

      <!-- 自動裝配: 只聲明 bean, 而把 bean 之間的關系交給 IOC 容器來完成 -->
          <!--
              byType: 根據類型進行自動裝配. 但要求 IOC 容器中只有一個類型對應的 bean, 若有多個則無法完成自動裝配.
              byName: 若屬性名和某一個 bean 的 id 名一致, 即可完成自動裝配. 若沒有 id 一致的, 則無法完成自動裝配
          -->
          <!-- 在使用 XML 配置時, 自動轉配用的不多. 但在基于 注解 的配置時, 自動裝配使用的較多.  -->
          <bean id="car" class="com.spring.demo.bean.Car">
              <property name="company" value="大眾"/>
              <property name="brand" value="寶來"/>
              <property name="price" value="200000.00"/>
              <property name="maxSpeed" value="200"/>
          </bean>
      
          <bean id="person" class="com.spring.demo.bean.Person" autowire="byName">
              <property name="name" value="James"/>
              <property name="age" value="23"/>
              <property name="car" ref="carSub"/>
          </bean>
      
         <!-- <bean id="person1" class="com.spring.demo.bean.Person" autowire="byType">
              <property name="name" value="James"/>
              <property name="age" value="23"/>
          </bean>-->
      
          <!--
              自動裝配的缺點:
                  1.autowire默認會為bean裝配全部屬性,所以當你只想裝配部分屬性時顯得不夠靈活;
                  2.byName和byType兩種模式只能選擇一個,不能兼有。
                  
          -->
      
       @Test
          public void testByName() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Person person = (Person) context.getBean("person");
              System.out.println(person);
          }
      
          @Test
          public void testByType() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Person person = (Person) context.getBean("person1");
              System.out.println(person);
          }
      

      10.bean的繼承與依賴

      作為一個Java程序員,肯定會接觸到繼承。Spring中也提供了bean的繼承,思想和面向對象的繼承的思想相似。區別在于Spring中的bean的繼承是指bean的配置可以被繼承(復用)。

      <!--
              bean的繼承:
                  你可以定義一個bean并有其他bean繼承,這樣做的好處是能減少配置
                  父bean的配置會由子bean繼承,當然部分屬性除外(autowire,abstract)
                  子bean可以重新賦值一些屬性,進行bean重新定義
                  父bean可以定義為abstract,定義為abstract的bean只能被繼承,不能被注冊(實例化)
                  父bean可以不定義class屬性,由子類自己定義
                  子bean需要通過parent屬性指定你繼承的父bean
          -->
          <bean id="carSup" class="com.spring.demo.bean.Car" p:company="寶馬" p:brand="mini"
                p:maxSpeed="270" p:price="300000.00" abstract="true"/>
      
          <bean id="carSub" parent="carSup"/>
      
       @Test
          public void testInherit() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Car car = (Car) context.getBean("carSub");
              System.out.println(car);
          }
      

      在本文的開頭,我們引入了A類和B類,當你想創建A類時,而A類又必須有B類的變量時,便可以使用依賴來解決這件事:

      <!--
              bean的依賴:
                  你可以聲明當前bean依賴于哪些bean,這樣當前bean初始化之前會去初始化依賴的bean,
                  如果沒有注冊導致無法初始化便會報錯
                  依賴多個bean的時候,可以使用逗號或者空格分開
          -->
          <bean id="person1" parent="person" depends-on="carSub"/>
      
       @Test
          public void testDepends() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Person person1 = (Person) context.getBean("person1");
              System.out.println(person1);
          }
      

      9.bean的作用域

      Spring中的bean的作用域有以下幾種:
      singleton, property, request,session
      默認情況下,spring中每個bean只有一個實例,但是可以顯示指定。

      <!--
              bean的生命周期:
                  singleton:默認選項,IOC容器默認為每個bean只實例化一個實例,該實例在調用具體的bean之前完成。
                  property:原型。該方式下IOC容器會在每次調用bean的時候實例化一個新的實例,并且只有在調用時進行bean的初始化
                 request和session同JavaWeb中一樣,在此不多加介紹
          -->
      
          <bean id="dog" class="com.spring.demo.bean.Dog" p:name="haki" scope="prototype"/>
      
      package com.spring.demo.bean;
      
      import lombok.AllArgsConstructor;
      import lombok.Getter;
      import lombok.Setter;
      import lombok.ToString;
      
      @Getter
      @Setter
      @AllArgsConstructor
      @ToString
      public class Dog {
          private String name;
          public Dog() {
              super();
              System.out.println("dog's constructor");
          }
      }
      
      @Test
          public void testScope() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Dog dog = (Dog) context.getBean("dog");
              Dog dog1 = (Dog) context.getBean("dog");
              System.out.println(dog == dog1);
          }
      

      在上面的demo中,除了可以查看bean的創建個數,還應該查看bean的創建時機。

      posted @ 2019-04-11 15:36  本墨  閱讀(567)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本狂喷奶水在线播放212| 极品美女aⅴ在线观看| 一本一道av无码中文字幕麻豆| 亚洲精品色在线网站| 爱性久久久久久久久| 国产精品乱一区二区三区| 东京热一精品无码av| 漂亮人妻被黑人久久精品| 亚洲中文字幕精品无人区| 国产自拍在线一区二区三区| 国产精品露脸视频观看| 无码专区 人妻系列 在线| 久久精品av国产一区二区| 天堂影院一区二区三区四区| 亚洲午夜亚洲精品国产成人| 91久久偷偷做嫩草影院免费看| 亚洲日本国产精品一区| 亚洲欧美综合人成在线| 亚洲欧美偷国产日韩| 久久精品一本到99热免费| 日韩av熟女人妻一区二| 国产美女久久久亚洲综合| 国产高清一区二区三区视频| 老太脱裤让老头玩ⅹxxxx| 平远县| 色av专区无码影音先锋| 久久综合色之久久综合色| 国产成人MV视频在线观看| 欧美老熟妇又粗又大| 国产午夜成人久久无码一区二区| 精品一区二区三区四区激情| 国产极品尤物免费在线| 通渭县| 国产亚洲精品第一综合| 国内少妇偷人精品免费| 国产超碰无码最新上传| 国内自拍小视频在线看| 丰满人妻被黑人猛烈进入| 九九热免费在线视频观看| 日本黄页网站免费观看| 日本系列亚洲系列精品|