1. 程式人生 > 實用技巧 >「2020最新」Spring最易學習教程—IOC 以及 整合Struts2

「2020最新」Spring最易學習教程—IOC 以及 整合Struts2

0 複習

  1. 工廠設計模式

    使用工廠代替new模式建立物件,目的:解耦合

  2. Spring工廠的使用

    applicationContext.xml中配置 bean標籤

    編碼:建立工廠,從工廠中獲取物件

  3. Spring中屬性注入

    1. 簡單型別(基本型別+包裝類+String)

      <beanid="標識名"class="全類名">
      <propertyname="屬性">
      <value></value>
      </property>
      <propertyname="屬性"value="值"/>
      </bean>
    2. 物件型別

      <beanid="a"
      class="Address的全類名">

      <propertyname="屬性1"value="值1"/>
      <propertyname="屬性2"value="值2"/>
      </bean>

      <beanid="p"class="Person全類名">
      <propertyname="addr">
      <refbean="a"/>
      </property>
      </bean>
      <beanid="p2"class="Person全類名">
      <propertyname="addr"ref="a"/>
      </bean>
    3. 陣列+List+Set

    4. Map+Properties

1 注入補充

1.1 null值

當需要顯式的為屬性賦值為 null 時,通過 null標籤完成。

<beanid="u"class="com.bcl.entity.User">
<constructor-argvalue="1"index="0"/>
<constructor-argvalue="xiaohei"index="1"/>
<constructor-argindex="2"><null/></constructor-arg>
</bean>

1.2 內部bean

<beanid
="a"class="com.bcl.entity.Address">

<propertyname="street"value="文化路"/>
<propertyname="city"value="矽谷"/>
</bean>

<beanid="p"class="com.bcl.entity.Person">
<propertyname="personId"value="1"/>
<propertyname="personName"value="xiaohei"/>
<propertyname="addr"ref="a"/>
</bean>

可以使用內部bean替換的寫法
<beanid="p"class="com.bcl.entity.Person">
<propertyname="personId"value="1"/>
<propertyname="personName"value="xiaohei"/>
<propertyname="addr">
<beanclass="com.bcl.entity.Address">
<propertyname="city"value="鄭州"/>
<propertyname="street"value="文化路"/>
</bean>
</property>
</bean>

2 FactoryBean技術(建立複雜物件)

2.1 FactoryBean引言

Spring工廠要管理程式中各種種類的物件。

image-20200601102514322

2.2 FactoryBean的開發步驟

  1. 編碼 實現FactoryBean介面

    publicclassConnectionFactoryBeanimplementsFactoryBean<Connection>{
    @Override
    //返回複雜物件
    publicConnectiongetObject()throwsException{
    //1載入驅動
    Class.forName("com.mysql.jdbc.Driver");
    //2建立連線
    Stringurl="jdbc:mysql://localhost:3306/bcl2002?useUnicode=true&characterEncoding=utf8";
    Stringusername="root";
    Stringpassword="root";
    Connectionconn=DriverManager.getConnection(url,username,password);
    returnconn;
    }

    @Override
    //返回複雜物件的型別
    publicClass<?>getObjectType(){
    returnConnection.class;
    }

    @Override
    //複雜物件是否單例true:單例false:多例
    publicbooleanisSingleton(){
    returntrue;
    }
    }
  2. 配置

    <!--配置factoryBean的全類名,
    根據id:conn獲取到是Connection物件-->

    <beanid="conn"class="com.bcl.factory.ConnectionFactoryBean"/>

注意:

  • 根據id獲取到的複雜物件,不是FactoryBean
  • 可以根據&id獲取到FactoryBean
  • 複雜物件的單例與否,只與isSingleton方法有關

3 Spring中物件的生命週期(瞭解)

生命週期: 從生到死的過程。

  1. 多例時 (scope="prototype")

    物件在getBean時建立
  2. 單例時(scope="singleton")

    物件在工廠建立時隨之建立
    初始化:init-method:物件建立後,執行1次方法
    銷燬:destroy-method:物件銷燬時,執行1次的方法
    物件在工廠關閉時銷燬

4 Spring配置檔案分析

4.1 Spring配置檔案的拆分

應用複雜時,需要將配置檔案拆分成多個小的配置檔案,放置到不同模組,最後在總配置檔案中通過import標籤引入其它的小配置檔案。

<importresource="classpath:a/applicationContext-a.xml"/>
<importresource="classpath:b/applicationContext-b.xml"/>

4.2 Spring 中xsd檔案

xsd(XML Schema Definition)檔案,規定了一個xml可以使用哪些標籤、哪些屬性,以及它們的順序。

  1. xsd的基本使用

    image-20200601113429666

    使用xsd檔案,要配置xsd的名稱空間,以及檔案路徑對。

  2. 在一個xml中使用多個xsd

    image-20200601114026438
  3. 示例:

    image-20200601120115361

4.3 Spring配置檔案中拆分jdbc.properties

  1. 抽取jdbc.properties

    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/bcl2002?useUnicode=true&characterEncoding=utf8
    jdbc.username=root
    jdbc.password=root
    
  2. 讀取配置檔案

    <context:property-placeholderlocation="classpath:jdbc.properties"/>
  3. 使用jdbc.properties中的引數

    <beanid="conn"class="com.bcl.factory.ConnectionFactoryBean">
    <propertyname="driverClassName"value="${jdbc.driverClassName}"/>
    <propertyname="url"value="${jdbc.url}"/>
    <propertyname="username"value="${jdbc.username}"/>
    <propertyname="password"value="${jdbc.password}"/>
    </bean>

注意:${username} 會優先讀取作業系統使用者名稱,可以給引數新增字首進行區分。

5 Spring IOC和DI

IOC(Inversion Of Control)控制反轉 (思想)

DI(Dependency Injection)依賴注入 (實現手段)

控制:對於物件屬性賦值的控制權力。

image-20200601141742924

正向控制的問題:強耦合。

解決方案:控制反轉。

image-20200601142542072

結論:要解耦合,就不要new,轉為在spring配置檔案中通過配置的方式由工廠建立物件。

6 Spring整合Struts2

準備工作:建立好一個可執行的struts2專案。

6.1 整合效果

image-20200601152503882

Spring整合Struts2的效果:由Spring工廠建立Struts2需要的Action和Service.

6.2 實戰

匯入spring-web 依賴

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.26.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.3.16.3</version>
</dependency>
  1. tomcat啟動應用時,自動建立Spring工廠

    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>
  2. Struts2從Spring工廠中獲取Action

    applicationContext.xml

    <beanid="userService"class="com.bcl.service.impl.UserServiceImpl"/>
    <beanid="userAction"class="com.bcl.action.UserAction"scope="prototype">
    <propertyname="userService"ref="userService"/>
    </bean>

    struts.xml

    <packagename="day02"extends="struts-default"namespace="/day02">
    <!--
    class配置的是spring配置檔案中Action的id
    -->

    <actionname="showAllUsers"class="userAction"method="showAllUsers">
    <resultname="success">/showAllUsers.jsp</result>
    </action>
    </package>

7 Spring整合JUnit

之前的JUnit測試Spring框架,每次都需要讀取配置檔案,建立工廠,測試繁瑣。

解決方案:使用 spring-test 進行測試

準備工作:

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.26.RELEASE</version>
</dependency>

簡化測試:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
publicclassApplicationContextTest{
@Autowired
privateUseru;

@Test
publicvoidtestUser(){
System.out.println("u="+u);
}
}

8 Spring基於註解的配置方式

使用註解替換xml配置的好處:簡化配置、提高開發效率。

註解的不足:不利於配置的管理。

8.1 使用註解的思路

image-20200601165433399

操作思路:

使用Component註解替換bean標籤配置

使用Autowired註解替換property標籤

8.2 註解開發的步驟

  1. 給類和屬性添加註解

    @Component("userService")
    publicclassUserServiceImplimplementsUserService{
    ...
    }

    @Component("userAction")
    publicclassUserAction{
    @Autowired
    privateUserServiceuserService;

    publicvoidsetUserService(UserServiceuserService){
    this.userService=userService;
    }
    ...
    }
  2. 查詢註解:配置查詢註解的起始包名

    applicationContext.xml

    <!--
    <context:component-scanbase-package="com.bcl.action,com.bcl.service.impl"/>-->

    <context:component-scanbase-package="com.bcl"/>

8.3 核心註解

@Component

Component註解替換bean標籤,建立物件。與其作用相同還有3個註解:

@Controller 用在action層

@Service 用在service層

@Repository 用在dao層

注意事項:

  1. 後3個註解實際開發時使用頻率更高,比Component有更高的辨識度

  2. MyBatis框架中,Repository沒有使用場景

  3. 4個註解在使用時,都可以省略id引數。會有預設id:類名首字母小寫

    UserAction==> userAction UserServiceImpl ==> userServiceImpl

@Autowired

用於屬性注入。

注意事項:

  1. 預設根據型別查詢所需要的屬性物件
  2. Autowired 用於屬性上,底層通過反射操作屬性賦值
  3. Autowired用在set方法上,底層通過呼叫set方法賦值

@Qualifier

當Autowired注入屬性,Spring中有不止一個滿足條件的物件,為了分辨使用哪個物件,可以通過@Qualifier("bean的id") 確定。

@Controller("userAction")
publicclassUserAction{
@Autowired
@Qualifier("userServiceImpl2")
privateUserServiceuserService;
...
}

@Scope

決定是否單例。

@Controller("userAction")
@Scope("prototype")
publicclassUserAction{
...
}

業內標準:

  1. 對於自定義的型別,使用註解。比如:dao、service、action
  2. 第3方型別,使用xml。比如:資料庫連線池、事務管理器

「❤️ 帥氣的你又來看了我」

如果你覺得這篇內容對你挺有有幫助的話:

  1. 點贊支援下吧,讓更多的人也能看到這篇內容(收藏不點贊,都是耍流氓 -_-)

  2. 歡迎在留言區與我分享你的想法,也歡迎你在留言區記錄你的思考過程。

  3. 覺得不錯的話,也可以關注 程式設計鹿 的個人公眾號看更多文章和講解視訊(感謝大家的鼓勵與支援