Spring實戰 | 番外篇: 搭建Spring環境實現helloworld、Bean配置、Spring容器

1、IntelliJ IDEA搭建Spring環境,實現helloworld前端

2、spring簡介java

3、配置形式web

4、bean的配置方式spring

5、IOC和DI編程

6、在Spring的IOC容器裏配置bean設計模式

7、關於ApplicationContext的介紹網絡

8、依賴注入的方式session

9、Spring容器app

1、IntelliJ IDEA搭建Spring環境,實現helloworld框架

一、建立project

二、勾選Spring而後next

三、設置你項目所想要存放的路徑以及名字

四、這時候IntelliJ IDEA就會自動下載Spring所須要的jars,只須要等待就好。

五、下載好後,Spring的jars和配置文件都準備好了。

六、Spring實現hello world

普通的方法:

接着咱們運行一下這個程序,成功輸出了Hello Spring。

这里写图片描述

接下來咱們就要使用Spring了,首先在Spring的配置文件中加入以下內容。

<?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="helloWorld" class="HelloWorld">
    <property name="name" value="Spring"></property>
</bean>
</beans>

這時候咱們就配置好了HelloWorld Bean的信息,咱們再調用sayHello()方法的時候就不向以前同樣了,也須要3個步驟。

  1. 建立一個Spring的IOC容器對象
  2. 從IOC容器中獲取Bean實例
  3. 調用sayHello()方法
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloWorld {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void sayHello(){
        System.out.println("hello "+name);
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
        helloWorld.sayHello();
    }
}

這麼寫好像和本身以前編程的時候不同啊,能夠運行結果嗎,咱們直接試一下就好。

好像不太同樣啊,輸出了咱們想要的Hello Spring ,可是好像多了許多其餘的東西啊。這些實際上是Spring輸出的日誌而已。
第一次使用Spring,咱們明明沒有建立HelloWorld的實例對象,只是配置了下Spring的配置文件,怎麼就能得出正確的結果呢,這是由於咱們使用了Spring的IOC功能,把對象的建立和管理的功能都交給了Spring去管理,咱們須要對象的時候再和Spring去要就行。

那麼何時new的對象呢?

我也不知道,哈哈,因此首先修改一下HelloWorld類的構造方法和setter方法。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloWorld {
    private String name;

    public HelloWorld() {
        System.out.println("this is helloworld constructor");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("this is helloworld setName()");
        this.name = name;
    }

    public void sayHello(){
        System.out.println("hello "+name);
    }

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
        helloWorld.sayHello();
    }
}

而後直接添加斷點進入Debug模式。

咱們能夠看到,當執行到第一步建立IOC容器對象的時候就調用了HelloWorld類的構造方法和setter方法。

從上面的例子能夠看出:

舊方法:

一、建立helloworld實例

二、設置實例對象的name屬性

三、調用sayhello方法

spring:

一、建立spring的IOC容器

二、從IOC容器中獲取Bean對象

三、調用sayhello方法

而後咱們研究了spring是啥時候new對象的,能夠看出,spring幫咱們完成了前兩步,也就是建立實例對象和設置對象屬性,也就是說咱們能夠把對象的建立和管理工做交給spring去完成,只要寫好spring的配置文件便可。

2、spring簡介

一、spring是一個開源框架

二、spring是爲了簡化企業級應用開發而生

三、javabean實現EJB的功能

四、spring是Java一站式框架

spring優勢

一、方便解耦,簡單開發

二、支持AOP編程

三、支持聲明事務

四、方便程序測試

五、方便框架集合

六、下降開發難度

3、配置形式

一、基於xml文件的方式

二、基於註解的方式

4、bean的配置方式

一、經過全類名(反射)

二、經過工廠方法(靜態工廠方法&實例工廠方法)

三、FactoryBean

5、IOC和DI

IOC(inversion of control):其思想是反轉資源獲取的方式。傳統的資源查找方式要求組件向容器發起請求查找資源,做爲迴應,容器適時的返回資源。而應用了IOC以後,容器主動將資源推送給它所管理的組件,組件要作的僅是選擇一種合適的方式接收資源。這種行爲也被稱爲查找的被動形式。

DI(Dependency Injection):IOC的另外一種表達方式:即組件以一些預先定義好的方式(例如:setter方法)接收來自如容器的資源注入。相對於IOC而言,這種表述更爲直接。

6、在Spring的IOC容器裏配置bean

只有springIOC容器自己實例化後,才能從IOC容器裏獲取bean實例並使用。

spring提供了兩種類型的IOC容器實現:

一、beanFactory:是spring框架的基礎設施,面向spring自己

二、ApplicationContext:面向使用spring框架的開發者,幾乎全部的應用場合都直接使用ApplicationContext而非底層的beanFactory,提供了更多的高級特性,ApplicationContext是beanFactory的子接口。

7、關於ApplicationContext的介紹

ApplicationContext的主要實現類:

一、ClassPathXmlApplicationContext:從類路徑下加載配置文件

二、FileSystemXmlApplicationContext:從文件系統中加載配置文件

子接口ConfigurableApplicationContext 的做用:擴展於ApplicationContext,新增長兩個主要方法:refresh()和close(),讓ApplicationContext具備啓動、刷新和關閉上下文的能力。

ApplicationContext在初始化上下文時就實例化全部單例的bean。

WebApplicationContext是專門爲web應用而準備的,它容許從相對於web根目錄的路徑彙總完成初始化工做。

8、依賴注入的方式

spring支持3種依賴注入的方式

一、屬性注入

屬性注入即經過setter方法注入bean的屬性值或依賴的對象

屬性注入使用元素,使用name屬性指定bean的屬性名稱,value屬性或子節點屬性值

屬性注入是實際開發中最多見的注入方式

public void setName(String name)
{
    System.out.println("setName:"+name);
    this.name=name;
}
<bean id="helloWorld" class="spring.bean.HelloWorld">
    <property name="name" value="Spring"></property>
</bean>

二、構造器注入

經過構造方法注入bean的屬性值或者依賴的對象(引用),保證了bean實例在實例化後就可使用

構造器注入在元素裏聲明屬性,沒有name屬性

建立一個People對象

package com.container;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class People {
        private String name;
        private String sex;
        private int age;

        public People(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public People(String name, String sex) {
            this.name = name;
            this.sex = sex;
        }

        @Override
        public String toString() {
            return "people{" +
                    "name='" + name + '\'' +
                    ", sex='" + sex + '\'' +
                    ", age=" + age +
                    '}';
        }

        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
            People people1 = (com.container.People) applicationContext.getBean("people1");
            System.out.println(people1);
            People people2 = (com.container.People) applicationContext.getBean("people2");
            System.out.println(people2);
        }
    }
<?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="people1" class="com.container.People">
        <constructor-arg value="江疏影" type="java.lang.String"></constructor-arg>
        <constructor-arg value="20" type="int"></constructor-arg>
    </bean>
    <bean id="people2" class="com.container.People">
        <constructor-arg value="江疏影" type="java.lang.String"></constructor-arg>
        <constructor-arg value="man" type="java.lang.String"></constructor-arg>
    </bean>
</beans>

三、工廠方法注入(知道就行,不推薦)

9、spring容器

Spring容器,顧名思義是用來容納東西的,裝的就是Bean。Spring容器負責建立、配置、管理Bean。spring容器有兩個核心接口:BeanFactory和ApplicationContext接口,後者是前者的子接口。在基於spring的Java EE程序中,全部的組件都被當成Bean來處理,包括數據源對象、hibernate的sessionFactory、事務管理等,程序中的全部Java類均可以被當成spring容器中的bean。

 一、spring容器

spring容器的核心接口是BeanFactory,它有一個子接口就是ApplicationContext。ApplicationContext也被稱爲spring上下文。

調用者只須要使用getBean()方法便可得到指定bean的引用。對於大部分的Java程序而言,使用ApplicationContext做爲spring容易更爲方便。其經常使用的實現類有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和AnnotationConfigXmlApplicationContext。若是Java web中使用spring容器,則一般有XmlWebApplicationContext、AnnotationConfigWebApplicationContext兩個容器。

建立spring容器的實例時,必須提供spring容器管理的bean的配置文件,也就是咱們常說的spring.xml配置文件。所以在建立beanFactory時配置文件做爲參數傳入。xml配置文件通常以resource對象傳入。resource是spring提供的資源訪問接口,經過該接口spring更簡單、透明的訪問磁盤,網絡系統和類路徑上的相關資源。

對於獨立的Java EE應用程序,能夠經過以下方法來實例化BeanFactory。

//在當前項目類路徑下搜索配置文件
ApplicationContext appContext = new ClassPathXmlApplicationContext("beans_7_3_3.xml");
//在文件系統搜索配置文件
appContext = new FileSystemXmlApplicationContext("D:\\spring-tool-workspace\\myspring\\src\\beans_7_3_3.xml");
//獲取chinese的Bean,而且返回的類型爲Chinese
Person chinese = appContext.getBean("chinese", Chinese.class);
chinese.useAxe();

二、使用ApplicationContext

大部分時間,都不會使用beanFactory實例做爲spring容器,而是使用ApplicationContext做爲spring容器,所以spring容器也被稱爲spring上下文。ApplicationContext加強了beanFactory的功能,提供了不少有用、方便開發的功能。

在web中能夠利用如contextLoader的支持類,在web應用啓動的時候自動建立ApplicationContext。

除了提供beanFactory所支持的所有功能外,application還額外的提供以下功能:

① ApplicationContext會默認初始化全部的singleton bean(單例bean),也能夠經過配置取消。

② ApplicationContext繼承了messageSource接口,所以提供國際化支持。

③ 資源訪問,好比URL和文件。

④ 事件機制。

⑤ 同時加載多個配置文件。

⑥ 以聲明式方式啓動並建立spring容器。

ApplicationContext包括beanFactory的全部功能,並提供了一些額外的功能,優先使用ApplicationContext。對於在內存消耗的才使用beanFactory。

當系統建立ApplicationContext容器時,會默認初始化singleton bean,包括調用構造器建立該bean的實例,經過元素驅動spring調用setting方法注入所依賴的對象。這就意味着,系統前期建立ApplicationContext會有很大的開銷,可是一旦初始化完成後面獲取bean實例就會擁有較好的性能。爲了阻止在使用ApplicationContext做爲spring容器初始化singleton bean能夠在元素添加lazy-init="true"屬性。

三、ApplicationContext的國際化支持

ApplicationContext接口繼承了MessageSource接口,所以具有國際化功能。

//MessageSource接口提供的國際化的兩個方法
String getMessage(String code, Object [] args, Locale loc){
}
String getMessage(String code, Object[]args, String default, Locale loc){
}

spring國際化的支持,實際上是創建在Java國際化的基礎上的。其核心思路將程序中須要國際化的消息寫入資源文件,而代碼中僅僅使用國際化信息響應的key。

四、ApplicationContext的事件機制

ApplicationContext的事件機制是觀察者設計模式的實現。經過ApplicationEvent和ApplicationListener接口實現,前者是被觀察者,後者是觀察者。

spring事件框架有兩個核心的接口:

ApplicationEvent(事件):必須由ApplicationContext來發布。

ApplicationListener(監聽器):實現了此接口就能夠擔任容器中的監聽器bean。

實際上,spring的事件機制是由事件(實現ApplicationEvent接口的類)、事件源(也就是spring容器,而且有Java代碼顯示的觸發)、監聽器(ApplicationListener接口實現類)。這就像咱們在頁面點擊一個button。button是事件源,單機的這個動做就是事件,處理函數就是監聽器。

如下代碼演示spring事件機制:

import org.springframework.context.ApplicationEvent;

public class EmailEvent extends ApplicationEvent{
    private String address;
    private String text;
    public EmailEvent(Object source) {
        super(source);
    }

    public EmailEvent(Object source, String address, String text) {
        super(source);
        this.address = address;
        this.text = text;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class EmailNotifier implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        //處理email事件
        if(event instanceof EmailEvent){
            EmailEvent email = (EmailEvent) event;
            System.out.println(email.getAddress()+"  "+email.getText());
        }else {
            //輸出spring容器的內置事件
            System.out.println("其它事件:"+event);
        }
    }

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_7_4_4.xml");
        EmailEvent emailEvent = applicationContext.getBean("emailEvent",EmailEvent.class);
        applicationContext.publishEvent(emailEvent);
    }
}
<?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 class="EmailNotifier"></bean>
    <bean id="emailEvent" class="EmailEvent">
        <constructor-arg value="test"></constructor-arg>
        <constructor-arg value="123@qq.com"></constructor-arg>
        <constructor-arg value="this is a test"></constructor-arg>
    </bean>
</beans>

從上面的代碼能夠看出,事件監聽器不只監聽到了咱們程序顯示觸發的事件,還監聽了spring容器內置的事件。若是實際開發須要,咱們能夠在spring容器初始化或銷燬時回調自定義方法,就能夠經過上面的事件監聽機制來完成。

spring提供了以下幾個內置對象:

ContextRefreshedEvent、ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent、RequestHandledEvent。

五、讓bean獲取spring容器

上面都是經過ApplicationContext建立spring容器,再調用spring容器的getBean()方法獲取bean。這種狀況下,程序老是持有spring容器的引用。可是在web應用中,咱們能夠用聲明式的方法來建立spring容器:在web.xml文件中配置一個監聽,讓這個監聽類幫咱們來建立spring容器,前端MVC框架直接調用bean,使用依賴注入功能,無需訪問spring容器自己。

在某些特殊狀況下,bean須要實現某個功能(好比:bean須要輸出國際化信息,或向spring容器發佈事件),這些功能都須要藉助spring容器來完成。就是說咱們須要將spring容器做爲一個bean來注入到其它bean中,只不過spring容器bean是一個容器級別的bean。

爲了讓bean獲取它所在容器的引用,可讓bean實現beanFactoryAware接口。該接口只有一個方法setBeanFactory(BeanFactory beanFactory)方法,方法的beanFactory參數指向spring容器,會由spring容器注入。咱們bean中定義一個setter方法後,一般都是由在配置文件中配置元素來驅動spring容器來注入依賴bean的,可是這裏咱們並無這樣作,這是由於一個bean若是實現了beanFactory接口,spring在建立該bean時,會自動注入spring容器自己。與beanFactoryAware接口相似的還有BeanNameAware、ResourceLoaderAware接口,這些接口都會提供相似的setter方法,這些方法會由spring容器來注入。

 

Spring實戰@目錄

相關文章
相關標籤/搜索