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

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

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

      Spiring系列__03IOC補(bǔ)充

      這篇文章是對(duì)前一篇的一些補(bǔ)充:

      1.SpringIOC容器可以管理Bean的生命周期:

      • 通過(guò)構(gòu)造器或工廠方法創(chuàng)建bean的實(shí)例;
      • 為bean屬性設(shè)置值或者引入其他bean;
      • 調(diào)用bean的初始化方法,此時(shí)bean就可以使用了;
      • 容器關(guān)閉時(shí),調(diào)用bean的清理方法
        在bean的聲明里定義init-method和的story-method,來(lái)定義bean的初始化方法和銷(xiāo)毀方法。

      2.bean的后置處理器

      bean的后置處理器允許spring在初始化方法前后,對(duì)bean進(jìn)行額外的處理,其會(huì)對(duì)IOC容器的所有bean實(shí)例進(jìn)行逐一處理,而非單一實(shí)例。例如:對(duì)bean實(shí)例檢查屬性的正確性或進(jìn)行相應(yīng)的更改。
      當(dāng)你想自定義一個(gè)后置處理器時(shí),需要實(shí)現(xiàn)Spring提供的BeanPostProcessor接口。

      package com.spring.demo.bean;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanPostProcessor;
      
      public class MyBeanProcessor implements BeanPostProcessor {
          @Override
          public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
              //添加過(guò)濾規(guī)則
              if ("car".equals(beanName)) {
                  System.out.println("postProcessBeforeInitialization:" + beanName + bean);
                  return bean;
              }
              return null;
          }
      
          @Override
          public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
              return bean;
          }
      
       <!--
              配置 bean 后置處理器: 不需要配置 id 屬性,
              IOC 容器會(huì)識(shí)別到他是一個(gè) bean 后置處理器, 并調(diào)用其方法
          -->
          <bean class="com.spring.demo.bean.MyBeanProcessor"/>
      

      在這個(gè)例子中,我只是在初始化bean之前對(duì)bean進(jìn)行了校驗(yàn),只是實(shí)例化car類(lèi)型。
      當(dāng)你自定義了一個(gè)后置處理器,并將其注冊(cè)到了Spring容器中,bean的聲明周期方法也會(huì)發(fā)生了一些改變:

      • 通過(guò)構(gòu)造器或工廠方法創(chuàng)建bean的實(shí)例;
      • 為bean屬性設(shè)置值或者引入其他bean;
      • 將bean實(shí)例傳遞給后置處理器的postProcessBeforeInitialization方法;
      • 調(diào)用bean的初始化方法,此時(shí)bean就可以使用了;
      • 將bean實(shí)例傳遞給后置處理器的postProcessAfterInitialization方法;
      • 容器關(guān)閉時(shí),調(diào)用bean的清理方法

      3.bean的創(chuàng)建方式續(xù)

      前一篇已經(jīng)介紹了了通過(guò)反射來(lái)創(chuàng)建bean的方法,現(xiàn)在介紹剩下的兩種:

      1.工廠方法

      其理念和設(shè)計(jì)模式中的工廠方法一樣。

      1.靜態(tài)工廠方法

      靜態(tài)工廠方法創(chuàng)建bean,不需要?jiǎng)?chuàng)建靜態(tài)工廠實(shí)例,只需調(diào)用對(duì)應(yīng)的靜態(tài)方法即可。

      <!--
              bean的配置方式2:工廠方法
                  靜態(tài)工廠方法:
                      id指定唯一標(biāo)識(shí)
                      class指定的是靜態(tài)工廠方法的類(lèi)
                      factory-method指定創(chuàng)建bean的工廠方法
          -->
          <bean id="carByStaticFactory" class="com.spring.demo.bean.StaticCarFactory" factory-method="getCar">
              <constructor-arg value="mini"/>
          </bean>
      
      
      //靜態(tài)工廠
      package com.spring.demo.bean;
      
      import java.util.HashMap;
      import java.util.Map;
      
      /**
       * 靜態(tài)方法來(lái)創(chuàng)建Car實(shí)例
       */
      public class StaticCarFactory {
      
          private static Map<String, Car> cars = new HashMap<>(10);
      
          static {
              cars.put("mini", new Car("mini", null, 200, 3000000.00));
              cars.put("BMW", new Car("BMW", null, 200, 5000000.00));
          }
      
          public static Car getCar(String name) {
              return cars.get(name);
          }
      }
      
      //測(cè)試方法
       @Test
          public void testStaticFactory() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Car car = (Car) context.getBean("carByStaticFactory");
              System.out.println(car);
          }
      

      2.實(shí)例工廠方法

      與靜態(tài)工廠方法不同,實(shí)例工廠方法需要實(shí)例一個(gè)工廠對(duì)象,其余的與靜態(tài)工廠方法類(lèi)似。

      <!--
              bean的配置方式2:工廠方法
                  實(shí)例態(tài)工廠方法:與靜態(tài)工廠方法類(lèi)似
                      id指定唯一標(biāo)識(shí)
                      class指定的是靜態(tài)工廠方法的類(lèi)
                      factory-bean指定工廠工廠方法實(shí)例
                      factory-method指定創(chuàng)建bean的工廠方法
          -->
          <bean id="carFactory" class="com.spring.demo.bean.CarFactory"></bean>
          <bean id="carByFactory" class="com.spring.demo.bean.Car" factory-bean="carFactory"
                factory-method="getCar">
              <constructor-arg value="mini"></constructor-arg>
          </bean>
      
      package com.spring.demo.bean;
      
      import java.util.HashMap;
      import java.util.Map;
      
      public class CarFactory {
          private Map<String, Car> cars = new HashMap<>(10);
      
          {
              cars.put("mini", new Car("mini", null, 200, 3000000.00));
              cars.put("BMW", new Car("BMW", null, 200, 5000000.00));
      
          }
      
          public Car getCar(String name) {
              return cars.get(name);
          }
      }
      
      @Test
          public void testFactory() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Car car = (Car) context.getBean("carByFactory");
              System.out.println(car);
          }
      

      2.FactoryBean

      Spring容器提供了一種新的bean的配置方式:FactoryBean。
      Spring容器中有兩種Bean:一種是普通的bean,另一種是工廠bean,即FactoryBeean。FactoryBean提供了getObject()來(lái)返回bean的實(shí)例。當(dāng)你通過(guò)這種方式時(shí),需要實(shí)現(xiàn)Spring的FactoryBean接口。

       <!--
              bean的配置方式3:FactoryBean
          -->
          <bean id="carByFacoryBean" class="com.spring.demo.bean.CarFactoryBean"/>
      
      package com.spring.demo.bean;
      
      import org.springframework.beans.factory.FactoryBean;
      
      /**
       * 自定義FactoryBean需要實(shí)現(xiàn)對(duì)應(yīng)的方法
       */
      public class CarFactoryBean implements FactoryBean<Car> {
      
          /**
           * 該方法返回創(chuàng)建的bean的引用
           * @return
           * @throws Exception
           */
          @Override
          public Car getObject() throws Exception {
              return new Car("BMW", "mini", 300, 2000000.00);
          }
      
          /**
           * 返回配置的bean的對(duì)應(yīng)的泛型
           * @return
           */
          @Override
          public Class<?> getObjectType() {
              return Car.class;
          }
      
          /**
           * 是否單例
           * @return
           */
          @Override
          public boolean isSingleton() {
              return true;
          }
      }
      
      @Test
          public void testFactory() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-autowire.xml");
              Car car = (Car) context.getBean("carByFactory");
              System.out.println(car);
          }
      

      3.注解方式

      可以采用注解方式來(lái)配置bean,不過(guò)需要配置主鍵掃描(其實(shí)組件掃描也可以通過(guò)注解實(shí)現(xiàn),達(dá)到純注解配置)
      組件掃描(component scanning): Spring 能夠從 classpath 下自動(dòng)掃描, 偵測(cè)和實(shí)例化具有特定注解的組件.

      • @Component: 基本注解, 標(biāo)識(shí)了一個(gè)受 Spring 管理的組件:
      • @Respository: 標(biāo)識(shí)持久層組件
      • @Service: 標(biāo)識(shí)服務(wù)層(業(yè)務(wù)層)組件
      • @Controller: 標(biāo)識(shí)表現(xiàn)層組件
        對(duì)于掃描到的組件,spring默認(rèn)使用類(lèi)名小寫(xiě)來(lái)命名,也可以通過(guò)value顯示指定。
      <context:component-scan base-package="com.spring.demo.autowire"/>
      
      @Test
          public void testComponentScan() {
              ApplicationContext context = new ClassPathXmlApplicationContext("bean-fac.xml");
              CarController controller = (CarController) context.getBean("carController");
              controller.test();
          }
      

      1.組件裝配

      context:component-scan 元素還會(huì)自動(dòng)注冊(cè) AutowiredAnnotationBeanPostProcessor 實(shí)例, 該實(shí)例可以自動(dòng)裝配具有 @Autowired 和 @Resource 、@Inject注解的屬性。

      1.使用 @Autowired 自動(dòng)裝配 Bean

      @Autowired 注解自動(dòng)裝配具有兼容類(lèi)型的單個(gè) Bean屬性

      • 構(gòu)造器, 普通字段(即使是非 public), 一切具有參數(shù)的方法都可以應(yīng)用@Authwired 注解
      • 默認(rèn)情況下, 所有使用 @Authwired 注解的屬性都需要被設(shè)置. 當(dāng) Spring 找不到匹配的 Bean 裝配屬性時(shí), 會(huì)拋出異常, 若某一屬性允許不被設(shè)置, 可以設(shè)置 @Authwired 注解的 required 屬性為 false
      • 默認(rèn)情況下, 當(dāng) IOC 容器里存在多個(gè)類(lèi)型兼容的 Bean 時(shí), 通過(guò)類(lèi)型的自動(dòng)裝配將無(wú)法工作. 此時(shí)可以在 @Qualifier 注解里提供 Bean 的名稱. Spring 允許對(duì)方法的入?yún)?biāo)注 @Qualifiter 已指定注入 Bean 的名稱
      • @Authwired 注解也可以應(yīng)用在數(shù)組類(lèi)型的屬性上, 此時(shí) Spring 將會(huì)把所有匹配的 Bean 進(jìn)行自動(dòng)裝配.
      • @Authwired 注解也可以應(yīng)用在集合屬性上, 此時(shí) Spring 讀取該集合的類(lèi)型信息, 然后自動(dòng)裝配所有與之兼容的 Bean.
      • @Authwired 注解用在 java.util.Map 上時(shí), 若該 Map 的鍵值為 String, 那么 Spring 將自動(dòng)裝配與之 Map 值類(lèi)型兼容的 Bean, 此時(shí) Bean 的名稱作為鍵值

      2.使用 @Resource 或 @Inject 自動(dòng)裝配 Bean

      Spring 還支持 @Resource 和 @Inject 注解,這兩個(gè)注解和 @Autowired 注解的功用類(lèi)似

      • @Resource 注解要求提供一個(gè) Bean 名稱的屬性,若該屬性為空,則自動(dòng)采用標(biāo)注處的變量或方法名作為 Bean 的名稱
      • @Inject 和 @Autowired 注解一樣也是按類(lèi)型匹配注入的 Bean, 但沒(méi)有 reqired 屬性
        建議使用 @Autowired 注解

      4.bean的作用域

      Spring容器的有以下幾種作用域:

      • 單例(singleton): 在整個(gè)應(yīng)用中,只創(chuàng)建bean的一個(gè)實(shí)例。
      • 原型(prototype): 每次注入或者通過(guò)Spring應(yīng)用上下文獲取的時(shí)候,都會(huì)創(chuàng)建一個(gè)新的bean的實(shí)例。
      • 請(qǐng)求(request): 在web應(yīng)用中,為每次請(qǐng)求創(chuàng)建一個(gè)bean實(shí)例。
      • 會(huì)話(session): 在web應(yīng)用中,為每個(gè)會(huì)話創(chuàng)建一個(gè)bean實(shí)例。
        在默認(rèn)情況下,Spring應(yīng)用上下文中所有bean都是單例的(線程不安全),這在大多數(shù)情況下是合理的;但是,有些情況下,你不希望如此。
        比如,電商應(yīng)用中的購(gòu)物車(chē),若是單例的,則所有人添加的商品都會(huì)添加到一個(gè)購(gòu)物車(chē)?yán)锩妫@就GG了。而現(xiàn)實(shí)生活中,你的購(gòu)物車(chē)是只有你能看到并進(jìn)行更改的。假設(shè)有一個(gè)Service對(duì)象來(lái)執(zhí)行這一業(yè)務(wù)邏輯:用戶登錄后添加商品到購(gòu)物車(chē)?yán)锩妗N覀儊?lái)分析一下:這個(gè)Service對(duì)象,應(yīng)該是單例的并且是隨著Spring容器加載而實(shí)例化好的;但是購(gòu)物車(chē)對(duì)象的對(duì)象應(yīng)該是session,并且應(yīng)該在用戶登錄后開(kāi)始向購(gòu)物車(chē)添加商品的時(shí)候才進(jìn)行實(shí)例化。而且,Service對(duì)象要想完成這一業(yè)務(wù)邏輯,需要依賴購(gòu)物車(chē)對(duì)象。
        簡(jiǎn)單概況:現(xiàn)在,一個(gè)作用域?yàn)閟ingleton的Serivce對(duì)象需要對(duì)一個(gè)作用域?yàn)閟ession的對(duì)象依賴。
        這時(shí),我們可以采取以下方案進(jìn)行設(shè)計(jì):
      /**
       * 購(gòu)物車(chē)對(duì)象,正常應(yīng)該一個(gè)用戶創(chuàng)建一次會(huì)話的時(shí)候就創(chuàng)建一個(gè)對(duì)象,作用域?yàn)閟ession
       */
      
      @Component
      @Scope(value = WebApplicationContext.SCOPE_SESSION,
              proxyMode = ScopedProxyMode.INTERFACES)
      public class ShoppingCart {
      }
      
      /**
       * 購(gòu)物車(chē)對(duì)象,正常應(yīng)該一個(gè)用戶創(chuàng)建一次會(huì)話的時(shí)候就創(chuàng)建一個(gè)對(duì)象,作用域?yàn)閟ession
       */
      
      @Component
      @Scope(value = WebApplicationContext.SCOPE_SESSION,
              proxyMode = ScopedProxyMode.INTERFACES)
      public class ShoppingCart {
      }
      

      解釋一下:Spring并不會(huì)將實(shí)際的購(gòu)物車(chē)對(duì)象注入到service對(duì)象中(購(gòu)物車(chē)還沒(méi)創(chuàng)建,也根本沒(méi)法注入),而是注入一個(gè)購(gòu)物車(chē)對(duì)象的代理,這個(gè)代理會(huì)暴露和購(gòu)物車(chē)一樣的方法,所以service對(duì)象就會(huì)認(rèn)為他是一個(gè)購(gòu)物車(chē)。
      而proxyMode屬性的值為ScopedProxyMode.INTERFACES,表明這個(gè)代理要實(shí)現(xiàn)ShoppingCart接口,并將調(diào)用委托給bean。
      如果shoppingcart是接口的話,這時(shí)可以的;但是當(dāng)其是一個(gè)具體類(lèi)的時(shí)候,Spring就不許使用CGlib來(lái)生成基于累的代理。
      當(dāng)然,當(dāng)你采用xml配置文件的形式的時(shí)候,只需要設(shè)置如下屬性即可:

      <bean id="cart" class="" scope="session">
          <aop:scoped-proxy/>
      </bean>  
      
      posted @ 2019-04-12 16:20  本墨  閱讀(670)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 精品久久国产字幕高潮| 久青草国产在视频在线观看| 成人午夜免费无码视频在线观看 | 成人精品大片—懂色av| 亚洲精品天堂在线观看| 国产午夜精品理论大片| 国产又色又爽又高潮免费| 日韩深夜视频在线观看| 中文字幕人乱码中文| 蜜臀视频在线观看一区二区| 亚洲精品中文字幕一区二| 国产一区二区三区黄色片| 精品久久精品午夜精品久久| 国产成人精品亚洲一区二区| 97精品人妻系列无码人妻| 国产欧美va欧美va在线| 国产一区二区不卡在线看| 国产激情无码一区二区三区| 国产呦交精品免费视频| 亚洲欧洲日产国无高清码图片| 精品 日韩 国产 欧美 视频| 午夜在线欧美蜜桃| 国产睡熟迷奷系列网站| 一边吃奶一边摸做爽视频| 国产精品中文字幕第一页| 国产久免费热视频在线观看| 凌云县| 激情五月日韩中文字幕| 国产成人一区二区三区视频免费 | 久久精品波多野结衣| 日韩区二区三区中文字幕| 狠狠色噜噜狠狠狠狠777米奇| 国产伦精品一区二区三区免费迷 | 四虎成人在线观看免费| 亚洲天堂男人的天堂在线| 久久成人影院精品777| 中文字幕亚洲精品第一页| 日本一区不卡高清更新二区| 精品国产亚洲第一区二区三区| 亚洲国产性夜夜综合| 最近2019免费中文字幕8|