乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      小白新手web開發(fā)簡(jiǎn)單總結(jié)(六)-Spring的IoC容器

       印度阿三17 2021-02-19

      目錄

      一 前言

      二 什么是IoC容器

      三 實(shí)例

      1.通過(guò)XML配置規(guī)則

      2.通過(guò)注解

      3.Spring中的其他幾種注解

      四 JavaBean生命周期的監(jiān)聽

      五 總結(jié)


      一 前言

      接上篇小白新手web開發(fā)簡(jiǎn)單總結(jié)(四)-web應(yīng)用開發(fā)中的MVC總結(jié)下IoC容器的相關(guān)內(nèi)容。

      IoC容器是Spring框架的一個(gè)核心功能。通過(guò)該容器來(lái)管理所有的JavaBean組件,提供組件的生命周期管理、配置和組裝、AOP支持、以及建立在AOP基礎(chǔ)上的聲明事務(wù)服務(wù)等。

      二 什么是IoC容器

      IoC(Inversion of Control 控制反轉(zhuǎn))容器

      通常Java組件通過(guò)new一個(gè)實(shí)例的方式實(shí)現(xiàn)組件之間的引用,并且組件中的兩個(gè)實(shí)例都含有共享組件的時(shí)候,也不能共享該組件。如果系統(tǒng)中有大量的組件的時(shí)候,不僅要維護(hù)組件的生命周期,還要維護(hù)組件之間的依賴關(guān)系,大大增加了系統(tǒng)的復(fù)雜度,而且組件之間會(huì)相互耦合,這些控制流程完全有開發(fā)者自行控制。

      而IoC容器就是將控制權(quán)進(jìn)行反轉(zhuǎn),將控制權(quán)交給了IoC容器,由IoC容器負(fù)責(zé)組件的創(chuàng)建和配置,負(fù)責(zé)組件的生命周期管理,而開發(fā)者只需要定義裝配規(guī)則,這樣就將組件的創(chuàng)建配置和組件的使用進(jìn)行分離。并且如果在一個(gè)組件的多個(gè)實(shí)例中含有共享組件的時(shí)候,是可以相互共享的,不需要多次注入。

      在Spring的IoC容器中,所有的組件都被成為JavaBean組件,每個(gè)組件即一個(gè)Bean。

      通常有兩種方式來(lái)定義組件的配置規(guī)則:

      • (1)XML
      • (2)注解

      三 實(shí)例

      通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)看下這個(gè)JavaBean組件是怎么定義配置規(guī)則。

      1.通過(guò)XML配置規(guī)則

      • 1.在項(xiàng)目pom.xml中引入spring-context依賴
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-context</artifactId>
                  <version>${spring.version}</version>
              </dependency>
      • 2.定義項(xiàng)目中需要使用的JavaBean

      (1)定義一個(gè)RegisterService:通過(guò)輸入的手機(jī)號(hào)碼和密碼,來(lái)注冊(cè)該用戶,并將注冊(cè)成功之后給用戶發(fā)送注冊(cè)成功的短信。

      public class RegisterService {
          private MessageService messageService;
      
          public void setMessageService(MessageService service) {
              this.messageService = service;
          }
      
          public User register(String phone, String password) {
              User user = new User();
              user.phone = phone;
              user.password = password;
              //隨機(jī)生成一個(gè)用戶名
              user.name = "小劉";
              //需要將該信息寫入數(shù)據(jù)庫(kù)
              SqlDataBase sql = new SqlDataBase();
              sql.insert(user);
              //注冊(cè)成功之后,給用戶發(fā)送短息
              if (messageService == null) {
                  System.err.println("還沒(méi)有初始化MessageService");
                  return user;
              }
              messageService.sendRegisterSuccessMessage(phone);
              return user;
      
          }
      
      }

      (2)定義MessageService:?向用戶的手機(jī)發(fā)送短信(邏輯省略)

      public class MessageService {
          /**
           * 發(fā)送短信
           *
           * @param phone
           */
          public void sendRegisterSuccessMessage(String phone) {
              String message = "您已經(jīng)成功注冊(cè)該網(wǎng)站賬戶";
              System.out.println(String.format("已經(jīng)成功的向%s發(fā)送注冊(cè)短信:%s", phone, message));
          }
      }
      • 3.定義配置JavaBean的規(guī)則

      (1)在resouce目錄下添加application-context.xml的文件

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www./schema/beans"
             xmlns:xsi="http://www./2001/XMLSchema-instance"
             xsi:schemaLocation="http://www./schema/beans
              https://www./schema/beans/spring-beans.xsd">
      
          <bean id="registerService" class="com.wj.spring.RegisterService">
              <property name="messageService" ref="messageService"/>
          </bean>
      
          <bean id="messageService" class="com.wj.spring.MessageService">
          </bean>
      </beans>

      其中id為該bean的唯一識(shí)別 ,通過(guò)?<property name="messageService" ref="messageService"/>的方式在RegisterService中增加了MessageService的引用,其實(shí)上面的XML配置的內(nèi)容就等價(jià)于下面的java代碼:

          MessageService messageService = new MessageService();
          RegisterService registerService = new RegisterService();
          registerService.setMessageService(messageService);
      
      • 4.通過(guò)讀取XML文件,獲取到ApplicationContext,也就是IoC容器
      public class RegisterApplication {
      
          public static void main(String[] args) {
              ApplicationContext context = new ClassPathXmlApplicationContext("config/application-context.xml");
              RegisterService service = context.getBean(RegisterService.class);
              //RegisterService service = (RegisterService)context.getBean("registerService");
              User user = service.register("12345678901", "123456");
              System.out.println("注冊(cè)之后的用戶名為:"   user.name);      
          }
      }

      當(dāng)?ClassPathXmlApplicationContext要傳入的是這個(gè)application-context.xml的相對(duì)路徑。這樣就可以context.getBean()的方式獲取到定義的JavaBean。運(yùn)行項(xiàng)目如下:

      相關(guān)的代碼已經(jīng)上傳到github:https://github.com/wenjing-bonnie/build-spring.git:對(duì)應(yīng)的com/wj/spring下的相關(guān)代碼。

      2.通過(guò)注解

      使用XML文件的方式,可以把所有的JavaBean的都一一列舉出來(lái),并且通過(guò)配置注入能直觀的了解到每個(gè)JavaBean的依賴關(guān)系,但是缺點(diǎn)也就顯現(xiàn)出來(lái),這種寫法非常繁瑣,每增加一個(gè)組件,就必須在XML將該組件添加進(jìn)去。所以就有了注解這種方式,可以讓IoC容器自動(dòng)掃描所有的Bean并組裝他們。

      • 1.同上面的1
      • 2.同樣定義同上面的JavaBean,只不過(guò)在JavaBean增加@Component注解,來(lái)標(biāo)示是一個(gè)JavaBean組件

      (1)定義一個(gè)RegisterService

      @Component
      public class RegisterAnnotationService {
          //   @Autowired將指定類型的Bean直接注入到指定的字段
          @Autowired
          private MessageAnnotationService messageAnnotationService;
      
      }
      

      通過(guò)?@Autowired將指定類型的Bean直接注入到指定的字段。當(dāng)然@Autowired也可以注解List<JavaBean>集合中,這樣每增加一個(gè)同類型的JavaBean,都會(huì)被IoC容器自動(dòng)裝配到該集合中。如果要設(shè)置JavaBean被裝配的順序,則可通過(guò)在組件上增加@Order(1)、@Order(2)……

      默認(rèn)情況下,當(dāng)給定字段標(biāo)記了?@Autowired,如果IoC容器沒(méi)有找到對(duì)應(yīng)的JavaBean,則會(huì)拋出NoSuchBeanDefinitionException異常,所以可以增加@Autowired(required=false)來(lái)避免該異常。

      (2)定義MessageService

      @Component
      public class MessageAnnotationService {
      
      }

      通過(guò)增加上面的兩個(gè)注解的方式,就完成了JavaBean之間的配置規(guī)則。

      默認(rèn)的將JavaBean標(biāo)記為@Component,那么IoC容器會(huì)自動(dòng)創(chuàng)建一個(gè)單例,即容器初始化的時(shí)候創(chuàng)建JavaBean,容器銷毀的時(shí)候銷毀。在整個(gè)容器運(yùn)行期間,getBean()獲取的是一個(gè)實(shí)例。

      其實(shí)可以通過(guò)@Scope來(lái)標(biāo)記該實(shí)例的作用域:即@Scope(value = "singleton")或@Scope( "singleton"),該value對(duì)應(yīng)的有四種作用域

      singleton :唯一的bean實(shí)例,默認(rèn)的為單例。即getBean()獲取的是一個(gè)實(shí)例。

      prototype:每次容器返回的都是一個(gè)新的實(shí)例。即getBean()獲取的都是一個(gè)新的實(shí)例。

      request:每次Http請(qǐng)求的時(shí)候都會(huì)產(chǎn)生一個(gè)新的實(shí)例,僅在當(dāng)前request請(qǐng)求中有效。

      session:每次Http請(qǐng)求的時(shí)候都會(huì)產(chǎn)生一個(gè)新的實(shí)例,僅在當(dāng)前session內(nèi)有效。

      • 3.通過(guò)讀取注解來(lái)獲得到IoC容器
      @Configuration  //用來(lái)標(biāo)明是一個(gè)配置類,在創(chuàng)建AnnotationConfigApplicationContext,需要傳入該類
      @ComponentScan //用來(lái)告訴容器,自動(dòng)掃描當(dāng)前類所在的包以及子包,把所有標(biāo)注為@Component的Bean都自動(dòng)創(chuàng)建出來(lái),并根據(jù)@Autowired進(jìn)行裝配
      public class RegisterAnnotationApplication {
      
          public static void main(String[] args) {
             ApplicationContext context = new  AnnotationConfigApplicationContext(RegisterAnnotationApplication.class);
              RegisterAnnotationService service = context.getBean(RegisterAnnotationService.class);
              //RegisterService service = (RegisterService)context.getBean("registerService");
              User user = service.register("12345678901", "123456");
              System.out.println("注冊(cè)之后的用戶名為:"   user.name);
          }
      }

      不同于通過(guò)XML文件的配置方式,在讀取ApplicationContext的時(shí)候,需要將該類增加一個(gè)?@Configuration ?用來(lái)標(biāo)明是一個(gè)配置類(其實(shí)@Configuration可以用@Component來(lái)代替,也就是如果分不清這個(gè)組件具體什么作用,那就直接用@Component),在創(chuàng)建AnnotationConfigApplicationContext的時(shí)候,需要傳入該類;增加@ComponentScan 用來(lái)告訴容器,自動(dòng)掃描當(dāng)前類所在的包以及子包,把所有標(biāo)注為@Component的Bean都自動(dòng)創(chuàng)建出來(lái),并根據(jù)@Autowired進(jìn)行裝配。

      運(yùn)行項(xiàng)目結(jié)果和上面的一致。相關(guān)代碼已經(jīng)上傳github:https://github.com/wenjing-bonnie/build-spring.git:對(duì)應(yīng)的com/wj/springannotation下的相關(guān)代碼。

      3.Spring中的其他幾種注解

      1.JavaBean組件相關(guān)的注解

      像之前大體有印象的一些@Controller/@RestController、@Service、@Respository等這些都是用來(lái)注解為JavaBean,只不過(guò)這是在后面的Spring MVC具有一些特殊功能的JavaBean,如果分不清該組件屬于哪一種,就直接使用@Component來(lái)注解。

      2.讀取配置文件、資源文件等相關(guān)注解

      • (1)讀取Resources下面的一些普通的文件

      使用IoC容器,可以很方便的把這些文件引入進(jìn)來(lái),方便程序讀取,省掉了很多繁瑣的代碼來(lái)獲取InputStream。在Maven項(xiàng)目中,經(jīng)常會(huì)將這些文件放置到Resources目錄下,所以Spring框架就提供了org.springframework.core.io.Resource來(lái)可以直接讀取到文件的InputStream

          @Value("readme.txt")
          private Resource readmeTxt;

      那么在項(xiàng)目中就可以通過(guò)readmeTxt.getInputStream()獲取到該txt的inputstream。

      • ?(2)讀取Resouces下的一些key/value結(jié)構(gòu)的文件

      經(jīng)常有些配置文件是key/value形式的存在文件中,在使用上面的方式,顯得不太方便,那么IoC容器還提供了更簡(jiǎn)便的方式來(lái)讀取。通過(guò)添加@PropertySource注解的方式,就可以直接根據(jù)key來(lái)獲取到對(duì)應(yīng)的value。例如有一個(gè)配置文件config/application.properties的內(nèi)容如下:

      application.ipaddress = 192.168.110.118

      我們只需要在需要讀取該配置文件的組件上添加?@PropertySource("config/application.properties"),那么就可以通過(guò)key來(lái)得到對(duì)應(yīng)的value值。

      @Configuration
      @PropertySource("config/application.properties")
      public class ApplicationConfig {
          @Value("${application.ipaddress}")
          public String ipAddress;
      }
      

      ?@Value("${application.ipaddress}"):為沒(méi)有默認(rèn)值的value,如果想給定默認(rèn)值的話,則?@Value("${application.ipaddress:192.168.0.0}")。

      • (3)在其他組件中引用配置文件的相關(guān)內(nèi)容

      還是上面的例子,如果在其他地方也要引用config/application.properties里面的配置項(xiàng),其實(shí)可以直接通過(guò)@Value("#{bean.property}")的方式來(lái)得到對(duì)應(yīng)的配置項(xiàng),bean就是ApplicationConfig的實(shí)例applicationConfig(該實(shí)例不需要引入,只是組件名的首字母小寫)的ipAddress屬性值引入到OtherAnnotation。

      @Component
      public class OtherAnnotation {
      
          @Value("#{applicationConfig.ipAddress}")
          public String ipAddress;
      }

      通過(guò)該注解方式,在OtherAnnotation中可以不用引入config/application.properties就可以讀取到定義在ApplicationConfig里面的配置項(xiàng)。與(2)不同的是,在(2)中使用的是@Value("${key:defaultValue}")的形式讀取配置文件中的值,而在OtherAnnotation中通過(guò)@Value("#{bean.property}")讀取在ApplicationConfig中讀到的配置項(xiàng)。

      四 JavaBean生命周期的監(jiān)聽

      當(dāng)我們將一個(gè)JavaBean添加到IoC容器時(shí),有的時(shí)候可能需要在容器初始化該JavaBean的時(shí)候監(jiān)聽消息等,在容器關(guān)閉的時(shí)候清理資源。那么就可以通過(guò)在該JavaBean只能夠定義兩個(gè)方法,在項(xiàng)目中引入javax.annotation依賴,通過(guò)javax.annotation的@PostContruct和@PreDestroy添加到上述的兩個(gè)方法中。其過(guò)程如下:

      (1)在pom.xml添加javax.annotation依賴

              <dependency>
                  <groupId>javax.annotation</groupId>
                  <artifactId>javax.annotation-api</artifactId>
                  <version>1.3.2</version>
              </dependency>

      (2)在MessageAnnotationService中需要承載初始化和銷毀的方法上添加@PostContruct和@PreDestroy

      public class MessageAnnotationService {
      
          @PostConstruct
          public void init() {
              System.out.println("MessageAnnotationService init");
          }
      
          @PreDestroy
          public void destroy() {
              System.out.println("MessageAnnotationService destroy");
          }
      }
      

      這樣在IoC容器初始化和銷毀的時(shí)候,就會(huì)看到對(duì)應(yīng)的方法的調(diào)用 。

      五 總結(jié)

      1.Spring的核心功能就是IoC容器,提供組件的創(chuàng)建和裝配,只需要定義配置規(guī)則,IoC容器會(huì)自動(dòng)完成所有的過(guò)程;

      2.可以通過(guò)XML文件和注解兩種方式來(lái)定義組件之間的配置規(guī)則;

      3.終于搞明白了項(xiàng)目中為什么有那么多bean的配置文件;

      4.使用@Component來(lái)注解一個(gè)類為組件,那么IoC容器在啟動(dòng)的時(shí)候,就會(huì)自動(dòng)初始化該組件;

      5.可以用@Scope來(lái)指定組件實(shí)例的作用域,是單例還是每次都是一個(gè)新的實(shí)例;

      6.一個(gè)ApplicationContext就是一個(gè)IoC容器,可以從ApplicationContext中通過(guò)getBean()來(lái)獲取到對(duì)應(yīng)的組件實(shí)例;

      7.使用javax.annotation可以在組件初始化或者銷毀的時(shí)候做一些事情;

      8.可以使用Resource輕松得到resouces下的文件的inputStream;

      9.可以通過(guò)?@PropertySource的方式輕松得到配置文件的key/value;

      10.之前有點(diǎn)印象的@Controller/@RestController、@Service、@Respository等其實(shí)都是一些組件,只不過(guò)是一些擁有特殊功能的組件。

      每天都在進(jìn)步一點(diǎn),加油?。?!?

      來(lái)源:https://www./content-4-862751.html

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多