小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 印度阿三17 2021-02-19

目錄

一 前言

二 什么是IoC容器

三 實例

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

2.通過注解

3.Spring中的其他幾種注解

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

五 總結(jié)


一 前言

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

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

二 什么是IoC容器

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

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

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

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

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

  • (1)XML
  • (2)注解

三 實例

通過一個簡單的實例來看下這個JavaBean組件是怎么定義配置規(guī)則。

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

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

(1)定義一個RegisterService:通過輸入的手機號碼和密碼,來注冊該用戶,并將注冊成功之后給用戶發(fā)送注冊成功的短信。

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;
        //隨機生成一個用戶名
        user.name = "小劉";
        //需要將該信息寫入數(shù)據(jù)庫
        SqlDataBase sql = new SqlDataBase();
        sql.insert(user);
        //注冊成功之后,給用戶發(fā)送短息
        if (messageService == null) {
            System.err.println("還沒有初始化MessageService");
            return user;
        }
        messageService.sendRegisterSuccessMessage(phone);
        return user;

    }

}

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

public class MessageService {
    /**
     * 發(fā)送短信
     *
     * @param phone
     */
    public void sendRegisterSuccessMessage(String phone) {
        String message = "您已經(jīng)成功注冊該網(wǎng)站賬戶";
        System.out.println(String.format("已經(jīng)成功的向%s發(fā)送注冊短信:%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的唯一識別 ,通過?<property name="messageService" ref="messageService"/>的方式在RegisterService中增加了MessageService的引用,其實上面的XML配置的內(nèi)容就等價于下面的java代碼:

    MessageService messageService = new MessageService();
    RegisterService registerService = new RegisterService();
    registerService.setMessageService(messageService);
  • 4.通過讀取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("注冊之后的用戶名為:"   user.name);      
    }
}

當?ClassPathXmlApplicationContext要傳入的是這個application-context.xml的相對路徑。這樣就可以context.getBean()的方式獲取到定義的JavaBean。運行項目如下:

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

2.通過注解

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

  • 1.同上面的1
  • 2.同樣定義同上面的JavaBean,只不過在JavaBean增加@Component注解,來標示是一個JavaBean組件

(1)定義一個RegisterService

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

}

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

默認情況下,當給定字段標記了?@Autowired,如果IoC容器沒有找到對應的JavaBean,則會拋出NoSuchBeanDefinitionException異常,所以可以增加@Autowired(required=false)來避免該異常。

(2)定義MessageService

@Component
public class MessageAnnotationService {

}

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

默認的將JavaBean標記為@Component,那么IoC容器會自動創(chuàng)建一個單例,即容器初始化的時候創(chuàng)建JavaBean,容器銷毀的時候銷毀。在整個容器運行期間,getBean()獲取的是一個實例。

其實可以通過@Scope來標記該實例的作用域:即@Scope(value = "singleton")或@Scope( "singleton"),該value對應的有四種作用域

singleton :唯一的bean實例,默認的為單例。即getBean()獲取的是一個實例。

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

request:每次Http請求的時候都會產(chǎn)生一個新的實例,僅在當前request請求中有效。

session:每次Http請求的時候都會產(chǎn)生一個新的實例,僅在當前session內(nèi)有效。

  • 3.通過讀取注解來獲得到IoC容器
@Configuration  //用來標明是一個配置類,在創(chuàng)建AnnotationConfigApplicationContext,需要傳入該類
@ComponentScan //用來告訴容器,自動掃描當前類所在的包以及子包,把所有標注為@Component的Bean都自動創(chuàng)建出來,并根據(jù)@Autowired進行裝配
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("注冊之后的用戶名為:"   user.name);
    }
}

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

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

3.Spring中的其他幾種注解

1.JavaBean組件相關的注解

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

2.讀取配置文件、資源文件等相關注解

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

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

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

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

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

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

application.ipaddress = 192.168.110.118

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

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

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

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

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

@Component
public class OtherAnnotation {

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

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

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

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

(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容器初始化和銷毀的時候,就會看到對應的方法的調(diào)用 。

五 總結(jié)

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

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

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

4.使用@Component來注解一個類為組件,那么IoC容器在啟動的時候,就會自動初始化該組件;

5.可以用@Scope來指定組件實例的作用域,是單例還是每次都是一個新的實例;

6.一個ApplicationContext就是一個IoC容器,可以從ApplicationContext中通過getBean()來獲取到對應的組件實例;

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

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

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

10.之前有點印象的@Controller/@RestController、@Service、@Respository等其實都是一些組件,只不過是一些擁有特殊功能的組件。

每天都在進步一點,加油?。。?

來源:https://www./content-4-862751.html

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多