Spring入門

Spring簡介

分層的,full-stack的輕量級開源框架

Spring兩大核心

  • IoC控制反轉 (反轉的是對象的創建權) 最大的優點是解耦合
  • AOP面向切面編程 底層實現是動態代理 作用:程序方法在不修改的情況下進行增強

Spring的各個層的解決方案:

  • web層: SpringMVC
  • service層 :
  • DAO層:
    • spring JDBC Templae(類似DBUtils)
    • Spring Data JPA\Redis\Solr\ES等

Spring的優勢

  1. 方便解耦 簡化開發
  2. AOP編程的支持
  3. 聲明式事務控制
    聲明式:與之對應的是編程式 : XML和註解都稱爲聲明
    1. 方便程序的測試
    2. 方便集成各種優秀框架
    3. 降低JavaEE的API的使用難度(封裝)

Spring的發展

  • Spring Boot (輕代碼 輕配置)
  • Spring Security 安全框架
  • Spring Cloud 用於分佈式開發

Spring快速入門(IoC:讓Spring框架創建Bean對象)

  1. 導入Spring相關jar包
    1. 導入核心容器的4個jar: beans, core, context, expression
    2. 框架會訪問日誌文件,導入日誌相關API: apache-commons-logging.jar
    3. 開發中習慣讓logging去繼承log4j ,自動集成
    4. 5.
  2. 創建bean
  3. 創建xml
  4. 測試

配置文件的配置

配置文件放在src目錄下,自己可以起名字,但是一般都是使用applicationContext.xml

0.導入約束

約束的位置在壓縮包

spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html

約束爲

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns=http://www.springframework.org/schema/beansxsi:schemaLocation="http://www.springframework.org/schema/beans ② http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ③">

① Xmlns(XML NameSpace) 聲明命名空間,建議是用網址做命名空間,但並不會去訪問改網址, 僅僅是 namespace 和 xsd(xsd 是 spring 這個 xml 的 schema 文件,裏面定義配置內容)裏 聲明的 targetNamespace 保持一致 . 注:這裏命名空間是改不了的,其實是在代碼中也寫死了,可以打開 spring-beans3.2.0.M1-sources.jar 包的 org\springframework\beans\factory\xml\BeanDefinitionParserDelegate.java 查看對 http://www.springframework.org/schema/beans這個namespace的定義。
② schemaLoacation .用於綁定命名空間的 schema 文件,通常是用 URL 值對,中間用空格隔 開,前面 URL 是命名空間,後面 URL 爲 schema 的文件地址
③ xsd 的存放地址,如果沒有聲明,eclipse 會去網上下載.

1.基本配置

使用bean標籤進行配置,和以前三層架構解耦合用的BeanFactory差不多,只有”暱稱”和路徑
- id:bean的實例,在spring容器中一個唯一的標識
- class:bean的全限定名

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>

2.Bean標籤中scope的配置

scope的選擇:
- singleton(默認值):單例
- prototype:原形 多例
需要注意的是,單例模式下,配置文件被加載,spring容器創建的時候,Bean對象就被創建了;而在多例模式下,在調用getBean的方法的時候,Bean對象才被創建

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" scope="prototype"></bean>

3.Bean生命週期相關的方法配置

也是Bean標籤中的屬性
- init-method:指定Bean初始化的時候,執行的方法
- destroy-mothod:指定Bean銷燬時執行的方法

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>

通過這兩個屬性的設置,Bean中任何一個方法,都可以充當初始化方法,或銷燬方法

單例對象生命週期歸容器管理
多例歸JVM垃圾回收機制管理

4.Bean實例化的三種方式

1.通過Bean無參構造創建對象(以上例子都是通過該方式創建的,也是最常用的方法)

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>

2.通過靜態工廠的方式創建對象
如果一個Bean可以通過一個工廠的某個方法獲得,name我們可以使用靜態工廠的方式獲取它
它有三個屬性 id–>和以前一樣,用來標識這個Bean; class–>這個class是工廠的位置,因爲這個模式是通過工廠獲取的Bean; method–>標識出具體哪一個方法用來生成我們想要的Bean

<bean id="userDao" class="com.cuixiaoming.factory.StaticBeanFactory" factory-method="getUserDao"></bean>

3.通過實例工廠的方式創建對象
這個和上一個的區別是,這種方法中,工廠Bean已經被配置到了spring容器中,所以我們不需要用class標識出工廠的位置,我們是用另一個屬性factory-bean,標上工廠的id即可

<bean id="beanFactory" class="com.cuixiaoming.factory.InstanceBeanFactory"></bean>
<bean id="userDao" factory-bean="beanFactory" factory-method="getUserDao"></bean>

經過測試我發現,這兩個工廠的方式的時候,當spring容器加載的時候,factory-method標註的方法都會執行一次,然後等到每次創建對象的時候,又會執行;

5.依賴注入(DI)的設置

注入之前,要在被注入的Bean中將注入的東西設爲私有變量,並且提供set方法

property標籤(位於Bean標籤內)
- name: 是該實體的set方法的屬性名稱
- ref: 代表引用的id 引用容器中的那一個bean
- value: 注入普通字符串
- list: 注入list集合
- map: 注入map集合
- props: 注入props集合

1.注入Bean

我們用最基本的形式,要想執行dao層方法,需要先獲得service對象,然後service對象再獲得dao層對象,從而執行dao層方法,也就是說,需要在spring容器中獲取兩次;
如果,我們通過注入,將dao層對象注入到service對象中,我們在獲得service對象的時候,就能一起獲取到dao層對象,如下圖所示;
注入

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>

<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao" ></property>
</bean>

2.注入普通字符串

將一個字符串設爲私有變量,並提供名爲setStr()的set方法,這樣我們創建對象的時候,它裏面已經包含這個字符串變量了;

<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
    <property name="str" value="這是一個value"></property>
</bean>

3.注入集合

注入集合是非常重要的知識點
一般來說,也是先設置成私有變量並提供set方法;然後在property中寫個name,然後在標籤內部寫集合標籤

 <bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
        <!-- list集合的注入 -->
        <property name="strList" >
            <list>
                <value>第一個</value>
                <value>第二個</value>
                <value>第三個</value>
            </list>
        </property>
    <!-- map集合的注入,裏面兩個user放在最下面了 -->
      <property name="userMap">
            <map>
                <entry key="user1" value-ref="user1"></entry>
                <entry key="user1" value-ref="user2"></entry>
            </map>
        </property>
    <!-- property集合的注入-->
        <property name="prop">
            <props>
                <prop key="p1">123</prop>
                <prop key="p2">456</prop>
                <prop key="p3">789</prop>
            </props>
        </property>
    </bean>

    <!-- map集合裏面的兩個user -->
    <bean id="user1" class="com.cuixiaoming.domain.User">
        <property name="username" value="張三"></property>
        <property name="age" value="23"></property>
    </bean><bean id="user2" class="com.cuixiaoming.domain.User">
        <property name="username" value="李四"></property>
        <property name="age" value="24"></property>
    </bean>

6.屬性注入的三種方式

1.set注入

上面這些方式都是採用的set注入,就是在被注入的Bean裏面,將注入的東西提取私有,提供set方法,不再贅述

2.有參構造注入

通過被注入的Bean提供有參和無參構造,(這種注入不使用無參構造,但是沒有無參構造會導致其他功能不能使用,一般來說,只要給出有參構造,就要同時給出無參構造)

public UserDaoImpl() {
    System.out.println("dao層無參構造執行了");
}

public UserDaoImpl(String username,User user) {
    System.out.println("dao層有參構造執行了");
    System.out.println("username="+username);
    System.out.println("user=" +user);
}

配置文件
在Bean標籤裏面使用constructor-arg標籤,這個標籤可以使用鍵值,也可以繼續注入其他Bean

<bean id="user1" class="com.cuixiaoming.domain.User">
    <property name="username" value="張三"></property>
    <property name="age" value="23"></property>
</bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl">
    <constructor-arg name="username" value="奧特曼"></constructor-arg>
    <constructor-arg name="user" ref="user1"></constructor-arg>
</bean>

<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>

需要注意的是,你的bean中constructor-arg的數據要至少和一個構造方法所有參數吻合,不然會報錯

3.p命名空間注入

這個方法也是使用set方法進行的注入,不過,語法非常簡單
首先,在約束上面加上這一句,就是把第一個約束複製改一下

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       <!--加上下面這一句,通過第一句修改而來-->
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

可以看出,它可以替代所有的set注入,而且語句極其簡單

<bean id="user1" class="com.cuixiaoming.domain.User" p:username="張三" p:age="23"></bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" p:str="這是一個字符串" p:user-ref="user1"></bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>

7.導入其他的配置文件

這個是用於分佈式開發,把多個配置文件合成一個
使用下面這個標籤即可

<import resource=""/> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章