1. 程式人生 > >Java框架-Spring概念及純xml配置

Java框架-Spring概念及純xml配置

1. 三層架構中的spring及spring概述

1.1 三層架構中的spring

在這裡插入圖片描述

  • Spring框架對三層架構都有支援,dao提供支援(如JDBCTemplate)、service提供事務支援、web提供了springmvc框架支援等。

1.2 Spring的概述

  • Spring是於2003年興起的一個輕量級的Java開發開源框架。
  • 由Rod Johnson首次提出。
  • Spring的核心是控制反轉(IoC)和麵向切面(AOP)。簡單來說,Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架

1.3 Spring優勢

  • 方便解耦,簡化開發
  • AOP程式設計的支援
  • 宣告式事務的支援
  • 方便程式的測試
  • 方便繼承各種優秀的框架
  • 降低JavaEE API的使用難度等

1.4 Spring體系結構

七大模組

  1. Spring Core:核心容器,Spring的基本功能
  2. Spring AOP:面向切面程式設計
  3. Spring ORM:提供多個第三方持久層框架的整合
  4. Spring DAO:簡化DAO開發
  5. Spring Context:配置檔案,為Spring提供上下文資訊,提供了框架式的物件訪問方法
  6. Spring Web:提供針對Web開發的整合特性
  7. Spring MVC:提供了Web應用的MVC實現

2. 程式中的耦合與解耦

  • 耦合:程式中的依賴關係。其中一種依賴關係是物件之間的關聯性。物件之間關聯性越高,維護成本越高。

  • 劃分模組的一個準則就是高內聚低耦合

  • 高內聚,低耦合:類內部的關係越緊密越好,類與類之間的關係越少越好。

2.1 解決資料庫驅動註冊程式碼與連線資料庫程式碼的耦合問題

  1. 使用反射註冊驅動,用於解決兩者依賴關係;
  2. 將驅動全限定類字串寫入配置檔案中,註冊驅動時載入配置檔案,用於使用反射建立物件時驅動類字串在程式碼中寫死的問題

2.2 解決三層架構之間的耦合問題

表現層需要建立業務層的例項來呼叫業務層的方法,同樣業務層也要建立持久層的示例來呼叫持久層的方法。按照傳統開發方法,建立例項都是直接new,一旦更換資料庫或者拓展已有業務(新的業務層介面例項),就會影響到原有的程式碼,需要修改原始碼(也就是耦合問題)

解決耦合問題的關鍵,業務層或持久層的例項不手動直接建立,而是交由第三方(工廠)建立。通過修改工廠的配置檔案獲取對應的例項,不需要修改原有程式碼,實現解耦

下面簡單舉例

2.2.1 舉例準備工作

  1. dao介面

    public interface IAccountDao {
        void save();
    }
    
  2. dao實現類

   //mysql
   public class AccountDaoImpl implements IAccountDao {
       @Override
       public void save() {
           System.out.println("mysql儲存使用者");
       }
   }

//oracle

public class AccountDaoOracleImpl implements IAccountDao {
    @Override
    public void save() {
        System.out.println("oracle儲存使用者");
    }
}
  1. service介面

    public interface IAccountService {
        void save();
    }
    
  2. service實現類

    public class AccountServiceImpl implements IAccountService {
        private IAccountDao accountDao = new AccountDaoImpl();
        @Override
        public void save() {
            accountDao.save();
        }
    }
    

2.2.2 使用工廠解耦

2.2.2.1 配置檔案
#dao層
#mysql
AccountDao=com.azure.dao.impl.AccountDaoImpl
#oracle
#AccountDao=com.azure.dao.impl.AccountDaoOracleImpl

#service層
AccountService=com.azure.service.impl.AccountServiceImpl
2.2.2.2 工廠類
public class BeanFactory {
    /*
    讀取properties配置檔案有兩種方式:
    1、直接建立properties物件,使用關聯配置檔案的輸入流載入檔案資料到properties中;
    2、通過ResourceBundle載入配置檔案
        1)只可以載入properties字尾的配置檔案
        2)只能載入類路徑下的properties配置檔案
     */
    //讀取配置檔案並建立對應的物件
    //使用泛型,通過傳入泛型型別返回對應型別的物件
    public static <T> T getBean(String name,Class<T> clazz) {
        try {
            //讀取配置檔案資料
            ResourceBundle bundle = ResourceBundle.getBundle("instance");
            //獲取key對應的value。比如AccountDao=com.azure.dao.impl.AccountDaoImpl
            String value = bundle.getString(name);
            return (T) Class.forName(value).getConstructor().newInstance();//jdk1.9做法
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
2.2.2.3 service層解耦
public class AccountServiceImpl implements IAccountService {
    private IAccountDao accountDao = BeanFactory.getBean("AccountDao", IAccountDao.class);
    @Override
    public void save() {
        accountDao.save();
    }
}
2.2.2.4 表現層解耦
  • 這裡就在測試類中模擬
public class app {
    public static void main(String[] args) {
        //使用工廠建立service物件
        IAccountService accountService = BeanFactory.getBean("AccountService", IAccountService.class);
        accountService.save();
    }
}
2.2.2.5 小結

通過修改配置檔案即可完成dao或service的轉換,不需要修改已有程式碼

3. IOC

使用工廠類實現三層架構的解耦,其核心思想就是

  1. 通過讀取配置檔案使用反射技術建立物件;
  2. 將建立的物件儲存。使用時直接取出儲存的物件。

其核心思想歸納起來就是IOC(Inversion Of Control 控制反轉)

3.1 IOC概念

  • 把建立物件的權利交給框架
  • 包含依賴注入(Dependency Injection)和依賴查詢(Dependency Lookup)

4. Spring IOC容器

  • 簡而言之,IOC容器是用來建立物件,並給物件屬性賦值

下面將建立一個簡單的IOC案例

4.1 建立簡單案例

4.1.1 建立專案、新增依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.azure</groupId>
    <artifactId>day51projects_spring_IOC</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!--引入spring-context包,包含了spring的核心ioc容器所需要的最小包。-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--引入junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>    
</project>

4.1.2 建立實體類

public class User implements Serializable {
    public User(){
        //使用無參例項化User物件時都會進入
        System.out.println("建立User物件");
    }
}

4.1.3 ioc容器配置檔案

  • 使用快捷方式建立,會自動引入約束

在這裡插入圖片描述

<?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">

    <!--Spring的IOC容器通過配置bean標籤表示要建立的物件-->
    <bean id="user" class="com.azure.entity.User"></bean>
</beans>

4.1.4 測試類

public class Test01 {
    @Test
    public void test(){
        //建立ioc容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //從容器中獲取物件
        User user = (User) ac.getBean("user");
        System.out.println(user);
    }
}

4.2 建立IOC容器的幾種方式

1.FileSystemXmlApplicationContext:載入本地的配置檔案

2.ClassPathXmlApplicationContext:載入類路徑下的配置檔案(重點)

3.AnnotationConfigWebApplicationContext:註解方式開發建立容器

4.WebApplicationContext:web專案中建立容器

5.BeanFactory:使用工廠建立物件

疑問:BeanFactory與ApplicationContext建立容器區別?

  • BeanFactory 在建立容器時候,沒有自動建立物件

  • ApplicationContext 在建立容器時候,預設自動建立物件。

public class Test02 {

    /*1.FileSystemXmlApplicationContext:載入本地的配置檔案*/
    @Test
    public void test_file(){
        //獲得配置檔案的真實路徑
        String path = "E:\\Java_study\\JavaprojectsIV\\day51projects_spring_IOC\\src\\main\\resources\\bean.xml";
        //從容器中獲取物件
        ApplicationContext ac = new FileSystemXmlApplicationContext(path);
        User user = (User) ac.getBean("user");
        System.out.println(user);
    }

    /*2.ClassPathXmlApplicationContext:載入類路徑下的配置檔案(重點)*/
    @Test
    public void test_class(){
        //類路徑下要有bean.xml
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //從容器中獲取物件
        User user = (User) ac.getBean("user");
        System.out.println(user);
    }

    /*3.AnnotationConfigWebApplicationContext:註解方式開發建立容器*/
    @Test
    public void test_annotation(){
        /*//程式中要有SpringConfig類,表示容器類(相當於bean.xml)
        ApplicationContext ac = new AnnotationConfigApplicationContext("SpringConfig.class");
        //從容器中獲取物件
        User user = (User) ac.getBean("user");
        System.out.println(user);*/
    }
    /*4.使用BeanFactory頂級介面建立容器*/
    @Test
    public void test_factory(){
        Resource resource = new ClassPathResource("bean.xml");
        BeanFactory factory = new XmlBeanFactory(resource);
        User user = (User) factory.getBean("user");//建立User物件
    }
}

4.3 建立容器(bean標籤)的具體配置

  • 常用配置

    id、class,可選scope、lazy-init、init-method、destroy-method

<!--
    建立物件的細節
    bean 標籤: 用來建立物件
    其屬性值包括:
        - id  (常用)指定物件的名稱,一次指定一個引用名稱。單例模式下所獲取物件只有一個
        - name 指定物件的名稱,一次可以指定多個名稱,多個名稱之間用逗號或者空格隔開。單例模式下多個名稱所獲取的物件均為同一個
        - class 指定物件的全路徑
        - scope 表示物件範圍,可選值有:
            singleton 單例 (預設值,建立容器時候就建立物件)
            prototype 多例(始終都是在使用的時候建立新的物件)
            request   (少用)物件範圍與request域一致,只在web專案有此選項
            session   (少用)物件範圍與session域一致,只在web專案有此選項
            global session (少用)在分散式系統使用,如果不是分散式系統相當於session,只在web專案有此選項
        - lazy-init="true" 延遲初始化,表示單例的物件在第一次使用時候才建立。該屬性對多例模式無效果。
        - init-method="init"  建立物件之後執行
        - destroy-method="preDestroy" 容器銷燬之前執行。只對單例有效,單例下只建立一個物件,每次獲取都是同一個,ioc容器會儲存該物件,所以可以呼叫該物件的preDestory方法。
           但多例模式無效,因為每次建立都是不同的物件,ioc容器不會儲存物件,所以無法呼叫物件的preDestory方法
-->
    <bean
            id="user"
            name="user2,user3"
            class="com.azure.entity.User"
            scope="prototype"
            lazy-init="true"
            init-method="init" destroy-method="preDestory"></bean>
  • 注意事項:

    id和name的作用相同,均是指定物件的名稱,用於通過該名稱獲取ioc容器中的物件。但是形式不同。id不能指定多個名稱,name可以指定多個名稱。按照實際開發,更常用的是id

4.4 建立物件的方式(控制反轉)

4.4.1 呼叫無參建構函式建立物件

  • 使用無引數建構函式建立物件(有引數建構函式在依賴注入中講述)
  1. 建立實體類

    在這裡插入圖片描述

  2. 在bean.xml中配置對應的bean標籤
    在這裡插入圖片描述

4.4.2 使用工廠類的例項方法

  1. 建立工廠類

    public class UserFactory {
        /*1.通過例項方法返回物件*/
        public User createUser(){
            System.out.println("工廠例項方法建立一個物件");
            return new User();
        }
    }
    
  2. 配置bean.xml

    • 運用到的bean標籤屬性:
      • factory-bean:用於指定引用容器中的工廠物件;
      • factory-method:用於指定工廠物件的例項方法。
    <!--1.使用工廠例項方法建立物件-->
    <!--1.1 建立工廠類-->
    <bean id="factory" class="com.azure.factory.UserFactory"></bean>
    <!--1.2 呼叫工廠例項方法-->
    <!--factory-bean用於指定引用容器中的工廠物件-->
    <!--factory-method用於指定工廠物件的例項方法-->
    <bean id="user" factory-bean="factory" factory-method="createUser"></bean>
    

4.4.3 使用工廠類的靜態方法

  1. 工廠類中新增靜態方法

    *2.通過靜態方法返回物件*/
    public static User createUser_static(){
        System.out.println("工廠靜態方法建立一個物件");
        return new User();
    }
    
  2. 配置bean.xml

    <!--2.使用工廠靜態方法建立物件-->
    <!--class與factory-method在同一個bean標籤中使用,不會建立class物件。-->
    <bean id="user1" class="com.azure.factory.UserFactory" factory-method="createUser_static"/>
    

4.5 給物件屬性賦值(DI依賴注入)

4.5.1呼叫有參建構函式建立物件

  1. 建立實體類物件

    public class Student {
        private int id;
        private String name;
        //使用有參建構函式建立物件,實體類必須有有參建構函式
        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }
        /*省略toString、getter&setter*/
    }
    
  2. 配置bean.xml

  • 常用index、value和ref三個屬性

    <!--使用有參建構函式建立物件-->
    <!--
    有參建構函式:
    constructor-arg 通過建構函式給物件屬性賦值
        - index 表示第幾個引數,從0開始
        - value 引數值
        - name 對應建構函式形參名稱 如建構函式public User(int id,String name)中的引數id或者name
        - type 表示建構函式引數的型別;如果是引用物件寫型別全名
        - ref  引數的值是引用容器中的另外一個物件(重點)
    -->
    <bean id="student" class="com.azure.entity.Student">
        <constructor-arg index="0" value="10"></constructor-arg>
        <constructor-arg index="1" ref="str"></constructor-arg>
    </bean>
    <!--建立字串並存入ioc容器中-->
    <bean id="str" class="java.lang.String">
        <constructor-arg index="0" value="明明"></constructor-arg>
    </bean>
    

4.5.2 使用set方法注入依賴

  1. 建立實體類物件,並提供set方法給物件屬性賦值

    • 注意:實體類物件必須有無參建構函式
  2. 配置bean.xml

    <!--使用set方法注入依賴-->
    <!--
    1.在bean標籤體中使用property標籤賦值
      配置property標籤,相當於呼叫set方法給物件屬性賦值。
        <property name="id"  相當於呼叫public void setId(int id);
    2.總結:
      1)property標籤是給物件的屬性賦值
      2)property標籤的name屬性值不能亂寫,必須是物件屬性名
        物件屬性名:get或者set方法後面的部分且首字母小寫。
        舉例:void setId(..) 中的id就是屬性
    -->
    <bean id="student2" class="com.azure.entity.Student">
        <property name="id" value="12"></property>
        <property name="name" ref="str"></property>
    </bean>
    

4.5.3 使用p名稱空間注入依賴

  • 也是呼叫set方法給物件屬性賦值

  • 在spring3.0之後版本才有的,主要目的是為了簡化配置

  • 配置bean.xml,配置時要在beans標籤中引入xmlns:p="http://www.springframework.org/schema/p"

<!--使用p名稱空間賦值-->
    <!--p:id 相當於呼叫setId()方法
        p:name-ref 相當於呼叫setName()方法,傳入的值引用的是容器中的物件
-->
    <bean id="student3" class="com.azure.entity.Student" p:id="168" p:name-ref="str"></bean>

4.6 給集合屬性賦值

  1. 實體類,要有set/get方法

    在這裡插入圖片描述

  2. 配置bean.xml

    <!--給集合屬性賦值-->
    <bean id="students" class="com.azure.entity.Student">
        <!--給list集合賦值-->
        <property name="list">
            <list>
                <value>cn</value>
                <value>usa</value>
            </list>
        </property>
    
        <!--給set集合賦值-->
        <property name="set">
            <set>
                <value>cn</value>
                <value>usa</value>
            </set>
        </property>
    
        <!--給map集合賦值-->
        <property name="map">
            <map>
                <entry key="cn" value="China"/>
                <entry key="usa" value="America"/>
            </map>
        </property>
    
        <!--給properties集合賦值-->
        <property name="properties">
            <props>
                <prop key="cn">China</prop>
                <prop key="usa">America</prop>
            </props>
        </property>
    </bean>
    

5. 使用純xml改造三層架構案例

  1. 新增依賴(pom.xml)

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            
                
               

    相關推薦

    Java框架-Spring念及xml配置

    1. 三層架構中的spring及spring概述 1.1 三層架構中的spring Spring框架對三層架構都有支援,dao提供支援(如JDBCTemplate)、service提供事務支援、web提供了springmvc框架支援等。 1.2 Spring的

    Java框架-Spring基於註解的IOC配置註解

    註解配置與xml配置都實現了減低程式間耦合的功能。 不同公司由不同習慣,有可能是純xml、純註解(很少)或者xml與註解混合使用(基於註解的IOC配置)。 1. 基於註解的IOC配置 1.1 建立一個簡單案例 1.1.1 建立專案,新增依賴(pom.xml)

    使用Spring框架入門一:基於XML配置的IOC/DI的使用

    測試結果 plugins rac prepare lombok ray instance private mls 一、Spring框架   1、方法一:逐項導入基礎依賴包:     spring-core、spring-beans、spring-context、s

    spring事務管理,xml配置aop事務和註解配置aop事務

    mov ref itcast template password nds eth poi ntc xml配置和註解配合共同代碼 AccountService.java public interface AccountService { //轉賬方法

    java框架spring的依賴註入初步理解

    而是 理念 依賴 註入 屬於 程序設計 之前 調用 每次   java框架的spring作為整個工程的統領者,可以有效地管理各層的對象,有效的協調運行,當系統西藥重構時,可以極大地減少改寫代碼的量。   依賴註入和控制反轉屬於同一個概念,在java中當某個類(調用者)需要另

    Java框架spring Boot學習筆記(八):Spring相關概念

    擴展 靜態 輕量級 想要 spring配置 核心 使用 oot 調用方法 Spring是開源、輕量級、一站式框架。 Spring核心主要兩部分 aop:面向切面編程,擴展功能不是修改源代碼實現 ioc:控制反轉,比如一個類,在類裏面有方法(不是靜態的方法),想要調用類

    Java框架spring Boot學習筆記(十四):log4j介紹

    inf alt 技術分享 images 使用 image 詳細 配置文件 -128 功能 日誌功能,通過log4j可以看到程序運行過程的詳細信息。 使用 導入log4j的jar包 復制log4j的配置文件,復制到src下面         3.設置日誌級別    

    spring boot 導入xml配置文件所需註解和禁用自動配置類的註解

    gpo exclude col 開始 XML post 正在 pri ann 導入XML配置 如果您絕對必須使用基於XML的配置,我們建議您仍然從一個@Configuration類開始。然後您可以使用@ImportResource註釋來加載XML配置文件。

    Struts2框架使用(三)之struts.xml配置

    package row port dtd tac 結構 www. turn doc 在Struts2的配置文件中,可以采用分模塊的方法來配置,在功能復雜的系統中,使用分模塊方法,可以使結構更清晰。 例如: 下面,有車輛模塊以及資產模塊,將其分為兩個xml文件。 <?

    Java DB 訪問之 mybatis mapper xml 配置方式

    exist nal div align ransac rep pre java db jdb 1 項目說明 項目采用 maven 組織 ,jdbc 唯一的依賴就是 mysql-connector-java pom 依賴如下: mysql 數據連接 : mysql

    JAVA框架 Spring 依賴註入

    div 設置 color pack ssp getbean lap support .com 一:介紹 情景:我們在給程序分層的時候:web層、業務層、持久層,各個層之間會有依賴。比如說:業務層和持久層,業務層的代碼在調用持久層的時候,傳統方式:new 持久層類。 進而進行

    JAVA框架 Spring 註解註入

    .html class IT soft pri 涵蓋 java 復制 掃描 一、首先需要引入jar包:spring-aop-4.2.4.RELEASE.jar。(在spring解壓包libs內)。 二、如果註解方式註入依賴的對象,需要引用新的約束。 內的:xsd-conf

    Java框架-Spring MVC理解001

    welcome 如果 bean resource onf lang spa lan 檢測 Spring MVC理解 最近在讀一本《看透springMVC》的書,從了解到了一些更加精細系統的知識,邊讀變分享吧。 1.servlet--Spring MVC的本質 2.Sprin

    Java框架-Spring MVC理解002-關聯源代碼

    java 精華 -a lib info style png 搜索結果 優秀 Spring MVC-關聯源代碼 首先說一下我們為什麽要關聯源代碼:   其實,我覺得閱讀源碼是一個非常好的學習方式,在我們日常工作中或多或少都會接觸一些開源代碼,比如說最常用的非常流行的Strut

    騰訊分分彩源碼帶龍虎和玩法自言自語Spring依賴註入(XML配置)

    類屬性 aslist when sid one != spi 匿名 sam 至於基於XML依賴註入的過程,首先要找一個比較合適的入口,那就是getBean。那麽具體是怎麽實現的呢?首先寫個測試方法: ClassPathXmlApplicationContext app =

    JAVA 框架-Spring-AOP面向切面

    類型 .com fig cto assert onf con app urn AOP(Aspect Orient Programming),我們一般稱為面向方面(切面)編程,作為面向對象的一種補充,用於處理系統中分布於各個模塊的橫切關註點,比如事務管理、日誌、緩存等等。AO

    Java框架-Spring的jdbc、連線池及事務管理

    1. Spring的AOP程式設計 1.1 純xml程式設計 <!--通知配置型別--> <aop:config> <!--設定切面--> <aop:aspect ref="logger"> <!-

    cors跨域請求問題 關於spring -springmvc -mybatis .基於xml配置方式

    1:場景還原     今天要寫一個方法, 需求是  在購物車服務上,  呼叫一個個人中心的方法 ,用到了 跨域請求.      我就在個人中心的 上面寫了個方法, 並在springMVC.xml中,配置了    &

    SSH框架整合亂碼問題-web.xml配置亂碼過濾器

    <!-- 解決亂碼問題 --> <filter> <filter-name>characterEncoding</filter-name> <filter-class>org.springframework.web.

    Spring和Hibernate整合xml配置

    1、基於xml的配置 dbconfig.properties資料來源檔案配置 driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/databaseName user=root pass