spring 基礎一
- 1 介紹一下spring:
- 2 spring的優缺點:
- 3 Spring的架構體系
- 4 spring第一大特性 控制反轉 IOC : 建立物件
- 5 spring第二大特性 DI 依賴注入: 給屬性賦值
- 6 核心容器 Core container :核心容器,就是用來裝javaBean物件的容器。
- 7 Java Bean
- 8 spring 與 WEB的整合
- 9 spring註解的使用
- 10 spring與junit的整合
1 介紹一下spring:
spring管理你的業務物件,“一站式”解決方案,並貫穿表現層springmvc、業務層及持久層spring j dbc,與其他框架無縫結合。
Spring框架是一個為Java應用程式的開發提供了綜合、廣泛的基礎性支援的Java平臺。Spring幫助開發者解決了開發中基礎性的問題,使得開發人員可以專注於應用程式的開發。Spring框架本身亦是按照設計模式精心打造,這使得我們可以在開發環境中安心的整合Spring框架,不必擔心Spring是如何在後臺進行工作的。
Spring框架至今已集成了20多個模組。這些模組主要被分如下圖所示的核心容器、資料訪問/整合,、Web、AOP(面向切面程式設計)、工具、訊息和測試模組。
Spring是一個一站式的解決框架,對我們web開發當中的各個層級都有對應的解決方案。
2 spring的優缺點:
優點:高內聚低耦合
1.方便解耦,簡化開發
sping就是一個大工廠,可以將所有的物件建立和依賴關係維護,交給sprong管理
2.AOP程式設計的支援
Spring提供面向切面程式設計,可以方便的實現對程式進行許可權攔截,執行監控等功能
3.宣告式事務的支援
只需要通過配置就可以完成對事務的管理,不用動手程式設計
4.方便程式的測試
Spring對Junit4支援,可以通過註解方便的測試Spring程式
5.方便整合各種優秀框架
Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如: Struts, Hibernate, Mybatis, Quartz 等)的直接支援
6.降低JavaEE API的使用難度
Spring對JAvaEE開發中非常難用的一些API (JDBC, javaMail,遠端協調_,都提供了封裝,是這些API應用難度大大降低
7.IOC和DI
大大降低程式的耦合性,促進了低耦合,簡化了開發
- 缺點:
1.增加一定複雜度
2.依賴spring容器重
3. 配置檔案比較多,配置比較複雜
3 Spring的架構體系
Test:測試模組,spring可以與我們的junit進行整合做測試非常方便
Core container :核心容器,就是用來裝javaBean物件。
AOP:切面程式設計
Aspects:切面程式設計應用的一個模組,與我們aop共同組成spring當中的切面程式設計
Data Access:資料訪問
Web:對資料訪問的支援
Transactions:用於支援我們的事物處理。用於解決我麼業務層的事物處理問題
Messaging: 訊息佇列
4 spring第一大特性 控制反轉 IOC : 建立物件
4.1 IOC:
inversion of controller 控制反轉,什麼是控制反裝:就是將建立物件的過程或者說建立物件的許可權交給了spring框架來幫我們處理,我們再不用通過new的方式來建立Javabean物件,這個過程就叫做控制反轉, 通過spring容器主動建立物件,就是通過反射來建立物件。。
4.3 IOC與DI的區別與聯絡
- IOC是建立我們的物件
- DI就是為我們物件中的屬性賦值
- DI依賴於IOC,只有我們先建立物件,才能個屬性賦值
5 spring第二大特性 DI 依賴注入: 給屬性賦值
DI:dependency injection 依賴注入,就是建立物件之後,給屬性賦值的過程就叫做DI,說白了就是通過配置來給屬性賦值
- IOC與DI的關係:先建立物件,然後才有可能通過DI來進行賦值
- DI是屬性賦值,依賴於物件的建立,也就是依賴於IOC。
5.1 第一種屬性賦值: 通過set 方法進行屬性賦值
屬性的型別一定要匹配
<bean id = "date" class = "java.util.Date"></bean>
<bean id = "dog" class = "com.hzh.demo4.Dog">
<property name = "name" value = "金毛"></property>
<property name = "age" value = "4"></property>
<property name = "color" value = "紅色"></property>
</bean>
<bean id = "PersonProperty" class="com.hzh.demo4.Person">
<property name="name" value = "張三"></property>
<property name="age" value = "4"></property>
<property name = "dog" ref = "dog"></property>
<property name = "date" ref = "date"></property>
</bean>
5.2 第二種屬性賦值: 通過構造器(有參)給屬性賦值
無參 有參 都給
<bean id = "tom" class = "com.hzh.demo5.Tom">
<constructor-arg name = "color" value = "藍色"></constructor-arg>
<constructor-arg name = "name" value = "湯姆貓"></constructor-arg>
<constructor-arg name = "age" value = "12"></constructor-arg>
<constructor-arg name = "jerry" ref = "jerry"></constructor-arg>
</bean>
<bean id = "jerry" class = "com.hzh.demo5.Jerry">
<constructor-arg name = "name" value = "小老鼠"></constructor-arg>
<constructor-arg name = "age" value = "2"></constructor-arg>
</bean>
5.3 給集合屬性 List 賦值
<bean id = "collectProperty" class = "com.hzh.demo6.CollectProperty">
<property name = "lists">
<list>
<value>張三</value>
<value>list</value>
<value>123</value>
<value type = "java.lang.Integer">456</value>
<value>"lisi"</value>
<!--物件的引用-->
<ref bean="tom"/>
</list>
</property>
</bean>
5.4 給集合屬性 List 賦值
<bean id = "collectProperty" class = "com.hzh.demo6.CollectProperty">
<property name = "lists">
<list>
<value>張三</value>
<value>list</value>
<value>123</value>
<value type = "java.lang.Integer">456</value>
<value>"list"</value>
<ref bean="tom"/>
</list>
</property>
<property name="maps">
<map>
<entry key = "張三" value= "123"></entry>
<entry key = "list" value-ref= "jerry"></entry>
<!--字串 = 物件-->
<entry key = "lists" value-ref= "tom"></entry>
<!--字串 = 物件-->
<entry key-ref = "jerry" value-ref= "tom"></entry>
<!--物件 = 字串-->
<entry key-ref = "jerry" value= "王五"></entry>
</map>
</property>
</bean>
5.5 給集合屬性 set 賦值
</property>
<property name="sets">
<set>
<value>張三</value>
<value>123</value>
<value>123</value>
<ref bean="dog"/>
<ref bean="dog"/>
</set>
</property>
5.6 給集合屬性Property賦值
<!--注意properties的屬性賦值只能寫字串 -->
<property name="properties">
<props>
<prop key="list">34</prop>
<prop key="zhangsan">12</prop>
<prop key="中國">首都北京</prop>
</props>
</property>
6 核心容器 Core container :核心容器,就是用來裝javaBean物件的容器。
6.1 獲取容器的三種方式:
- 1 使用ClassPathXmlApplicationContext獲取容器類,ApplicationContext 是我們容器的一個子介面
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = (UserDao) context.getBean("userDao");
- 2 XmlBeanFactory來獲取容器類,已過時
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
UserDao dao = (UserDao) factory.getBean("userDao");
- 3 使用FileSystemXmlApplicationContext來獲取容器,需要傳入spring配置檔案的絕對路徑
可以使用外部的配置檔案
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:\\workspace_myProject\\springDemo\\src\\main\\resources\\applicationContext.xml");
UserDao dao = (UserDao)context.getBean("userDao");
7 Java Bean
7.1 IOC 建立Java Bean 的三種方式
在配置檔案載入完成之後就會建立配置的全部的JavaBean,並且放入到容器中
注意: 在建立Java Bean物件的時候對物件進行初始化,執行初始化方法
- 1 通過無參構造的方式建立:
- 條件: 必須有無參構造
<bean id = "createBean" class="com.hzh.springbean.UserBeanFactory">
</bean>
- 2 通過靜態工廠方式建立物件
- factory-method :工廠類的靜態方法.必須用static修飾
- 靜態方法必須有返回值
- class: 工廠類的相對路徑
< !-- 通過靜態工廠建立物件 -->
<bean id = "userBean2Factory" class = "com.hzh.springbean.UserBeanFactory2" factory-method="getFactory"></bean>
- 3 通過例項工廠獲取javaBean
- 工廠類的方法不需要static修飾
- factory-bean: 為工廠類物件
- factory-method: 為工廠類的方法.
- 第二個class : 返回物件類的相對路徑
<!-- 通過例項工廠獲取javaBean -->
<!-- 建立例項工廠 -->
<bean id = "userBean3Factory" class ="com.hzh.springbean.UserBean3Factory" ></bean>
<!-- 通過已經申明的工廠來獲取我們的javaBean物件 -->
<bean id = "userBean3" class = "com.hzh.springbean.UserBeanFactory2" factory-bean="userBean3Factory" factory-method="getBean2"></bean>
靜態工廠和例項工廠的區別就是方法有沒有靜態修飾
使用預設構造可以直接獲取某一個javaBean的物件
通過靜態工廠和例項工廠則可以一個工廠提供不同的JavaBean物件,只需要選擇相對應的工廠方法即可.
7.2 Spring Bean的作用域與作用範圍
Bean的作用域範圍有四種:
singleton 單列 預設 :
建立一個物件,每次呼叫,都使用這個物件
這種範圍確保不管接受到多少個請求,每個容器中只有一個bean的例項,單例的模式由bean factory自身來維護。
prototype 多例 :
每次呼叫都會建立一個新的例項 ,為每一個bean請求提供一個例項。
Request:
適用於web開發當中,將我們的物件儲存在request域中
Session:
適用於web開發當中,將我們的物件儲存在session中
7.3 java Bean 的生命週期
可以配置init-method與destroy-method來實現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生命週期的程式碼樣例如下:
- InitializingBean和DisposableBean回撥介面
<bean id = "userDemo" class="com.hzh.User" init-method="initMethod" destroy-method="destoryMethod"></bean>
如果要銷燬一個方法,則使用 ClassPathXmlApplicationContext類的物件呼叫 .close()即可
7.4 BeanFactory和ApplicationContext有什麼區別?
①ApplicationContext 介面繼承BeanFactory介面,Spring核心工廠是BeanFactory ,BeanFactory採取延遲載入,第一次getBean時才會初始化Bean, ApplicationContext是會在載入配置檔案時初始化Bean。
②ApplicationContext是對BeanFactory擴充套件,它可以進行國際化處理、事件傳遞和bean自動裝配以及各種不同應用層的Context實現
③從表面上看,application context如同bean factory一樣具有bean定義、bean關聯關係的設定,根據請求分發bean的功能。但application context在此基礎上還提供了其他的功能。
- 提供了支援國際化的文字訊息
- 統一的資原始檔讀取方式
- 已在監聽器中註冊的bean的事件
7.5 Spring通過配置檔案和註解的方式建立javaBean物件的比較
- 自己寫的java類,建議全部用註解的方式
- Jar包中的類,全部用配置檔案的方式
8 spring 與 WEB的整合
8.1 Spring為什麼要與我們的javaWeb整合???
我們是從spring容器中取出物件,那麼我們每請求一個java Bean 物件,就要建立一個spring容器嗎?,每建立一個spring容器,就要在jvm中開闢出一塊空間,分配地址,這樣會浪費我們的jvm資源,我們可不可以讓spring容器之建立一次?
整合思路:在我們建立javaWeb容器的時候,就會建立一個ServletContext物件,並且這個物件是唯一的,單例的,直到javaWeb容器關閉的時候,才會銷燬。
那麼問題來了,我們可不可以監聽ServletContext的啟動,如果監聽到ServletContext的啟動,我們馬上就去啟動我們的spring容器,也就是說,ServletContext只啟動一次,我們的spring容器也只啟動一次,將spring容器啟動成功之後,就把我們的spring容器放到ServletContext物件當中,以後需要使用spring容器,再不用自己去new了,直接從ServletContext當中獲取即可
8.2 匯入jar
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
8.3 監聽ServletContext的建立
- 在WEB-INF下的web.xml中配置監聽器:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
8.4 定義自己的servlet,在servlet請求中獲取spring容器
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1 獲取servletContext物件
ServletContext servletContext = request.getServletContext();
//2 從servletContext中取出spring容器,
WebApplicationContext attribute = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//3 獲取javaBean物件
Dog bean = (Dog) attribute.getBean("dog");
System.out.println("小狗的名字: "+bean.getName());
response.getWriter().append("Served at: ").append(request.getContextPath());
}
8.5 設定訪問路徑,訪問
如果使用tomcat外掛,配置了 :
<path>/</path>
則訪問時不用寫專案名: http://localhost:8080/ContextSerlvet
9 spring註解的使用
9.1 匯入jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
9.2 開啟註解
<!-- 開啟註解 -->
<context:annotation-config></context:annotation-config>
9.3 開啟包掃描
<!-- 包掃描 -->
<context:component-scan base-package="com/hzh/demo8"></context:component-scan>
9.4 使用註解
/**
* @Value("張三"):簡單型別的注入
*
* @Autowired : 複雜屬性的注入,會直接去spring容器中找注入的物件,不用關心 (value = "?"),即不用考慮類的ID.
*
* @Autowired+@Qualifier(value = "cat") :無論類名上面有沒有ID,(value = "?")必須有,類名有ID,?=類名ID,類名無ID,?=類名首字母小寫
*
* @Resource : 可以寫ID,也可以不寫ID,
*
* @Resource(name = "cat"): 如果寫ID,則要與我們類名的ID保持一致.
*/
@Component == @Controller == @Service [email protected]
@Controller 用於我們的資料展現層
@Service 用於我們的業務邏輯層
@Repository 用於我們的到層
@Value 用於我們簡單型別屬性的賦值
10 spring與junit的整合
10.1 匯入jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
<scope>test</scope>
</dependency>
10.2 在我們的測試類上新增兩個註解,並且指定我們的配置檔案所在的位置
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext-web.xml")