1、什麼是Spring框架?Spring框架有哪些主要模塊?
Spring框架是一個爲Java應用程序的開發提供了綜合、廣泛的基礎性支持的Java平臺。Spring幫助開發者解決了開發中基礎性的問題,使得開發人員可以專注於應用程序的開發。Spring框架本身亦是按照設計模式精心打造,這使得我們可以在開發環境中安心的集成Spring框架,不必擔心Spring是如何在後臺進行工作的。
Spring框架至今已集成了20多個模塊。這些模塊主要被分如下圖所示的核心容器、數據訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測試模塊。
更多信息:Spring 框架教程。
2、使用Spring框架能帶來哪些好處?
下面列舉了一些使用Spring框架帶來的主要好處:
Dependency Injection(DI) 方法使得構造器和JavaBean properties文件中的依賴關係一目瞭然。
與EJB容器相比較,IoC容器更加趨向於輕量級。這樣一來IoC容器在有限的內存和CPU資源的情況下進行應用程序的開發和發佈就變得十分有利。
Spring並沒有閉門造車,Spring利用了已有的技術比如ORM框架、logging框架、J2EE、Quartz和JDK Timer,以及其他視圖技術。
Spring框架是按照模塊的形式來組織的。由包和類的編號就可以看出其所屬的模塊,開發者僅僅需要選用他們需要的模塊即可。
要測試一項用Spring開發的應用程序十分簡單,因爲測試相關的環境代碼都已經囊括在框架中了。更加簡單的是,利用JavaBean形式的POJO類,可以很方便的利用依賴注入來寫入測試數據。
Spring的Web框架亦是一個精心設計的Web MVC框架,爲開發者們在web框架的選擇上提供了一個除了主流框架比如Struts、過度設計的、不流行web框架的以外的有力選項。
Spring提供了一個便捷的事務管理接口,適用於小型的本地事物處理(比如在單DB的環境下)和複雜的共同事物處理(比如利用JTA的複雜DB環境)。
3、什麼是控制反轉(IOC)?什麼是依賴注入?
控制反轉是應用於軟件工程領域中的,在運行時被裝配器對象來綁定耦合對象的一種編程技巧,對象之間耦合關係在編譯時通常是未知的。在傳統的編程方式中,業務邏輯的流程是由應用程序中的早已被設定好關聯關係的對象來決定的。在使用控制反轉的情況下,業務邏輯的流程是由對象關係圖來決定的,該對象關係圖由裝配器負責實例化,這種實現方式還可以將對象之間的關聯關係的定義抽象化。而綁定的過程是通過“依賴注入”實現的。
控制反轉是一種以給予應用程序中目標組件更多控制爲目的設計範式,並在我們的實際工作中起到了有效的作用。
依賴注入是在編譯階段尚未知所需的功能是來自哪個的類的情況下,將其他對象所依賴的功能對象實例化的模式。這就需要一種機制用來激活相應的組件以提供特定的功能,所以依賴注入是控制反轉的基礎。否則如果在組件不受框架控制的情況下,框架又怎麼知道要創建哪個組件?
在Java中依然注入有以下三種實現方式:
構造器注入
Setter方法注入
接口注入
4、請解釋下Spring框架中的IoC?
Spring中的 org.springframework.beans 包和 org.springframework.context包構成了Spring框架IoC容器的基礎。
BeanFactory 接口提供了一個先進的配置機制,使得任何類型的對象的配置成爲可能。ApplicationContex接口對BeanFactory(是一個子接口)進行了擴展,在BeanFactory的基礎上添加了其他功能,比如與Spring的AOP更容易集成,也提供了處理message resource的機制(用於國際化)、事件傳播以及應用層的特別配置,比如針對Web應用的WebApplicationContext。
org.springframework.beans.factory.BeanFactory 是Spring IoC容器的具體實現,用來包裝和管理前面提到的各種bean。BeanFactory接口是Spring IoC 容器的核心接口。
5、BeanFactory和ApplicationContext有什麼區別?
BeanFactory 可以理解爲含有bean集合的工廠類。BeanFactory 包含了種bean的定義,以便在接收到客戶端請求時將對應的bean實例化。
BeanFactory還能在實例化對象的時生成協作類之間的關係。此舉將bean自身與bean客戶端的配置中解放出來。BeanFactory還包含了bean生命週期的控制,調用客戶端的初始化方法(initialization methods)和銷燬方法(destruction methods)。
從表面上看,application context如同bean factory一樣具有bean定義、bean關聯關係的設置,根據請求分發bean的功能。但application context在此基礎上還提供了其他的功能。
提供了支持國際化的文本消息
統一的資源文件讀取方式
已在監聽器中註冊的bean的事件
以下是三種較常見的 ApplicationContext 實現方式:
1 、ClassPathXmlApplicationContext:從classpath的XML配置文件中讀取上下文,並生成上下文定義。應用程序上下文從程序環境變量中取得。 ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”); 2 、FileSystemXmlApplicationContext :由文件系統中的XML配置文件讀取上下文。 ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”); 3 、XmlWebApplicationContext:由Web應用的XML文件讀取上下文。 |
6、Spring有幾種配置方式?
將Spring配置到應用開發中有以下三種方式:
基於XML的配置
基於註解的配置
基於Java的配置
7、如何用基於XML配置的方式配置Spring?
在Spring框架中,依賴和服務需要在專門的配置文件來實現,我常用的XML格式的配置文件。這些配置文件的格式通常用<beans>開頭,然後一系列的bean定義和專門的應用配置選項組成。
SpringXML配置的主要目的時候是使所有的Spring組件都可以用xml文件的形式來進行配置。這意味着不會出現其他的Spring配置類型(比如聲明的方式或基於Java Class的配置方式)
Spring的XML配置方式是使用被Spring命名空間的所支持的一系列的XML標籤來實現的。Spring有以下主要的命名空間:context、beans、jdbc、tx、aop、mvc和aso。
< beans > <!-- JSON Support --> < bean name = "viewResolver" class = "org.springframework.web.servlet.view.BeanNameViewResolver" /> < bean name = "jsonTemplate" class = "org.springframework.web.servlet.view.json.MappingJackson2JsonView" /> < bean id = "restTemplate" class = "org.springframework.web.client.RestTemplate" /> </ beans > |
下面這個web.xml僅僅配置了DispatcherServlet,這件最簡單的配置便能滿足應用程序配置運行時組件的需求。
< web-app > < display-name >Archetype Created Web Application</ display-name > < servlet > < servlet-name >spring</ servlet-name > < servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class > < load-on-startup >1</ load-on-startup > </ servlet > < servlet-mapping > < servlet-name >spring</ servlet-name > < url-pattern >/</ url-pattern > </ servlet-mapping > </ web-app > |
8、如何用基於Java配置的方式配置Spring?
Spring對Java配置的支持是由@Configuration註解和@Bean註解來實現的。由@Bean註解的方法將會實例化、配置和初始化一個新對象,這個對象將由Spring的IoC容器來管理。@Bean聲明所起到的作用與<bean/> 元素類似。被@Configuration所註解的類則表示這個類的主要目的是作爲bean定義的資源。被@Configuration聲明的類可以通過在同一個類的內部調用@bean方法來設置嵌入bean的依賴關係。
最簡單的@Configuration 聲明類請參考下面的代碼:
@Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } } |
對於上面的@Beans配置文件相同的XML配置文件如下:
< beans > < bean id = "myService" class = "com.howtodoinjava.services.MyServiceImpl" /> </ beans > |
上述配置方式的實例化方式如下:利用AnnotationConfigApplicationContext 類進行實例化
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig. class ); MyService myService = ctx.getBean(MyService. class ); myService.doStuff(); } |
要使用組件組建掃描,僅需用@Configuration進行註解即可:
@Configuration @ComponentScan (basePackages = "com.howtodoinjava" ) public class AppConfig { ... } |
在上面的例子中,com.acme包首先會被掃到,然後再容器內查找被@Component 聲明的類,找到後將這些類按照Sring bean定義進行註冊。
如果你要在你的web應用開發中選用上述的配置的方式的話,需要用AnnotationConfigWebApplicationContext 類來讀取配置文件,可以用來配置Spring的Servlet監聽器ContrextLoaderListener或者Spring MVC的DispatcherServlet。
< web-app > <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext --> < context-param > < param-name >contextClass</ param-name > < param-value > org.springframework.web.context.support.AnnotationConfigWebApplicationContext </ param-value > </ context-param > <!-- Configuration locations must consist of one or more comma- or space-delimited fully-qualified @Configuration classes. Fully-qualified packages may also be specified for component-scanning --> < context-param > < param-name >contextConfigLocation</ param-name > < param-value >com.howtodoinjava.AppConfig</ param-value > </ context-param > <!-- Bootstrap the root application context as usual using ContextLoaderListener --> < listener > < listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class > </ listener > <!-- Declare a Spring MVC DispatcherServlet as usual --> < servlet > < servlet-name >dispatcher</ servlet-name > < servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class > <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext instead of the default XmlWebApplicationContext --> < init-param > < param-name >contextClass</ param-name > < param-value > org.springframework.web.context.support.AnnotationConfigWebApplicationContext </ param-value > </ init-param > <!-- Again, config locations must consist of one or more comma- or space-delimited and fully-qualified @Configuration classes --> < init-param > < param-name >contextConfigLocation</ param-name > < param-value >com.howtodoinjava.web.MvcConfig</ param-value > </ init-param > </ servlet > <!-- map all requests for /app/* to the dispatcher servlet --> < servlet-mapping > < servlet-name >dispatcher</ servlet-name > < url-pattern >/app/*</ url-pattern > </ servlet-mapping > </ web-app > |
9、怎樣用註解的方式配置Spring?
Spring在2.5版本以後開始支持用註解的方式來配置依賴注入。可以用註解的方式來替代XML方式的bean描述,可以將bean描述轉移到組件類的內部,只需要在相關類上、方法上或者字段聲明上使用註解即可。註解注入將會被容器在XML注入之前被處理,所以後者會覆蓋掉前者對於同一個屬性的處理結果。
註解裝配在Spring中是默認關閉的。所以需要在Spring文件中配置一下才能使用基於註解的裝配模式。如果你想要在你的應用程序中使用關於註解的方法的話,請參考如下的配置。
< beans > < context:annotation-config /> <!-- bean definitions go here --> </ beans > |
在 <context:annotation-config/>標籤配置完成以後,就可以用註解的方式在Spring中向屬性、方法和構造方法中自動裝配變量。
下面是幾種比較重要的註解類型:
@Required:該註解應用於設值方法。
@Autowired:該註解應用於有值設值方法、非設值方法、構造方法和變量。
@Qualifier:該註解和@Autowired註解搭配使用,用於消除特定bean自動裝配的歧義。
JSR-250 Annotations:Spring支持基於JSR-250 註解的以下註解,@Resource、@PostConstruct 和 @PreDestroy。
10、請解釋Spring Bean的生命週期?
Spring Bean的生命週期簡單易懂。在一個bean實例被初始化時,需要執行一系列的初始化操作以達到可用的狀態。同樣的,當一個bean不在被調用時需要進行相關的析構操作,並從bean容器中移除。
Spring bean factory 負責管理在spring容器中被創建的bean的生命週期。Bean的生命週期由兩組回調(call back)方法組成。
初始化之後調用的回調方法。
銷燬之前調用的回調方法。
Spring框架提供了以下四種方式來管理bean的生命週期事件:
InitializingBean和DisposableBean回調接口
針對特殊行爲的其他Aware接口
Bean配置文件中的Custom init()方法和destroy()方法
@PostConstruct和@PreDestroy註解方式
使用customInit()和 customDestroy()方法管理bean生命週期的代碼樣例如下:
< beans > < bean id = "demoBean" class = "com.howtodoinjava.task.DemoBean" init-method = "customInit" destroy-method = "customDestroy" ></ bean > </ beans > |
更多內容請參考:Spring生命週期Spring Bean Life Cycle。
11、Spring Bean的作用域之間有什麼區別?
Spring容器中的bean可以分爲5個範圍。所有範圍的名稱都是自說明的,但是爲了避免混淆,還是讓我們來解釋一下:
singleton:這種bean範圍是默認的,這種範圍確保不管接受到多少個請求,每個容器中只有一個bean的實例,單例的模式由bean factory自身來維護。
prototype:原形範圍與單例範圍相反,爲每一個bean請求提供一個實例。
request:在請求bean範圍內會每一個來自客戶端的網絡請求創建一個實例,在請求完成以後,bean會失效並被垃圾回收器回收。
Session:與請求範圍類似,確保每個session中有一個bean的實例,在session過期後,bean會隨之失效。
global-session:global-session和Portlet應用相關。當你的應用部署在Portlet容器中工作時,它包含很多portlet。如果你想要聲明讓所有的portlet共用全局的存儲變量的話,那麼這全局變量需要存儲在global-session中。
全局作用域與Servlet中的session作用域效果相同。
更多內容請參考 : Spring Bean Scopes。