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個步驟。
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容器來注入。