1. 程式人生 > >Spring框架[一]——spring概念和ioc入門(ioc操作xml配置文件)

Spring框架[一]——spring概念和ioc入門(ioc操作xml配置文件)

修改 數組 名稱空間 springmvc jdbc ack 靜態 spring框架 鍵值

Spring概念

技術分享

  • spring是開源的輕量級框架(即不需要依賴其他東西,可用直接使用)

spring核心主要兩部分

  • aop:面向切面編程,擴展功能不是修改源代碼來實現;
  • ioc:控制反轉,比如:有一個類,在類中有個方法(非靜態的方法),要調用類中的這個方法,則需要創建類的對象,使用對象調用方法。創建類對象的過程,需要new出來對象;而ioc則是將對象的創建不是通過new方式實現,而是交給spring配置來創建對象(即,將對象的創建交給spring來管理);

spring是一站式框架

  • spring在javaee三層結構中,每一層都提供不同的解決技術
    • web層:springMVC
    • service層:spring的ioc
    • dao層:spring的jdbcTemplate

spring版本

  • hibernate5.x
  • spring4.x

Spring入門

  • Spring的ioc操作
    • 把對象的創建交給spring進行管理
    • ioc兩種操作方式:
      • ioc的配置文件方式;
      • ioc的註解方式;

IOC底層原理

  • ioc底層原理使用的技術
    • xml配置文件
    • dome4j解析xml
    • 工廠設計模式
    • 反射
  • 畫圖分析ioc實現原理
    技術分享 技術分享

IOC入門案例

  • 步驟:
    • 導入jar包

      • 解壓下載的spring-framework-4.2.4.RELEASE.zip文件,jar包特點:都有三個jar包(基本jar、文檔jar、源碼jar);
        技術分享
      • 做spring基本功能,只需導入四個核心點jar包即可(Beans、core、Context、SpEL);
        技術分享
      • 導入支持日誌輸出的jar包-logging、log4j(因為spring本身沒有提供這種jar包);
        技術分享
    • 創建類,在類中創建方法
      package cn.cbb.ioc;
      
      public class User {
      
          public
      void add() { System.out.println("add ..."); } public static void main(String[] args) { /** * 調用類中的方法,原始做法是創建類對象,用對象調用方法;而現在則不再這樣做了, * 而是將對象的創建過程交給spring來配置實現,但是底層用的肯定是反射,我們不需 * 要寫反射代碼,由spring代我們做此操作 */ User user = new User(); user.add(); } }
    • 創建spring配置文件,配置創建類
      • spring核心配置文件名稱和位置不是固定的,建議放在src下面,官方建議applicationContext.xml
      • 引入schema約束
        技術分享
      • 配置對象創建,配置如下:
        <?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">
        
            <!-- ioc入門,配置對象的創建 -->
            <bean id="user" class="cn.cbb.ioc.User"></bean>
        </beans>
    • 寫代碼測試對象創建:
      package cn.cbb.ioc;
      
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class IOCTest {
      
          @Test
          public void IOCTest() {
              //1、加載spring配置文件,根據配置創建對象
              ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
              //2、得到配置創建的對象
              User user = (User) context.getBean("user");
              System.out.println(user);
              user.add();
          }
      }

配置文件無提示問題

Spring引入schema約束,把約束文件引入到eclipse中,以便配置文件編寫提示:
技術分享

spring的bean管理(xml配置文件)

bean實例化三種方式

  • bean實例化,即:在spring裏面通過配置文件創建對象;
  • bean實例化的三種方式實現(掌握一種,其他兩種知道即可):
    • 無參構造函數創建(重點)
      <!-- ioc入門,配置對象的創建 -->
      <bean id="user" class="cn.cbb.ioc.User"></bean>

      對象對應的類中,若沒有無參構造(定義了有參構造),則將出現異常

      org.springframework.beans.factory.BeanCreationException:...No default constructor found;...
    • 靜態工廠創建
      通過工廠創建的靜態方法來返回類對象(如:IOC底層原理圖析工廠類UserFactory創建的靜態方法getService
      <!-- 使用靜態工廠創建對象 -->
      <bean id="bean2Factory" class="cn.cbb.bean.Bean2Factory" factory-method="getBean2"></bean>
      package cn.cbb.bean;
      
      public class Bean2Factory {
      
          //靜態方法返回Bean2對象
          public static Bean2 getBean2() {
              return new Bean2();
          }
      }
    • 實例工廠創建
      通過工廠的非靜態方法來返回對象
      <!-- 使用實例工廠創建對象 -->
      <!-- 首先,創建工廠對象 -->
      <bean id="bean3Factory" class="cn.cbb.bean.Bean3Factory"></bean>
      <!-- 其次,通過實例化的工廠對象的方法來創建對象bean3 -->
      <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
      package cn.cbb.bean;
      
      public class Bean3Factory {
      
          //普通方法返回Bean3對象
          public Bean3 getBean3() {
              return new Bean3();
          }
      }

bean標簽常用屬性

  • id屬性:命名,可任意命名。
    • id屬性值,不能包含特殊符號;
    • spring是根據id值找到配置對象;
  • class屬性:創建對象所在類的全路徑
  • name屬性:功能和id屬性一致,都可以找到配置對象(主要區別:name可以包含特殊符號);現在用的較少,主要是為了整合strus1那種框架而遺留下來的一個屬性。
  • scope屬性:
    技術分享
    User user1 = (User) context.getBean("user");
    User user2 = (User) context.getBean("user");
    System.out.println(user1);
    System.out.println(user2);

    • singleton:默認值,單例
      <!-- 默認scope="singleton" -->
      <bean id="user" class="cn.cbb.ioc.User"></bean>
      cn.cbb.ioc.User@b7dd107
      cn.cbb.ioc.User@b7dd107
    • prototype:多例
      <!-- scope="prototype"測試 -->
      <bean id="user" class="cn.cbb.ioc.User" scope="prototype"></bean>
      cn.cbb.ioc.User@b7dd107
      cn.cbb.ioc.User@42eca56e

屬性註入方式介紹

  • 屬性註入:創建對象時,為對象的屬性設置值
  • 註入方式介紹(三種)
    技術分享
    • 屬性的setXXX方法註入
    • 有參構造註入
    • 接口註入

spring註入屬性(僅支持前兩種方式:有參構造和set方法)

  • set方式註入(最常用)
    <!-- 使用set方法註入屬性 -->
    <bean id="book" class="cn.cbb.property.Book">
        <!-- 註入屬性之:
            name屬性值:類中的屬性名稱; value屬性:設置的具體值
        -->
        <property name="bookName" value="紅樓夢"></property>
    </bean>
    package cn.cbb.property;
    
    public class Book {
    
        private String bookName;
        //set方法
        public void setBookName(String bookName) {
            this.bookName = bookName;
        }
        
        public void testBook() {
            System.out.println("bookName通過set註入值為:"+bookName);
        }
    }
  • 有參構造註入
    <!-- 使用有參數構造註入屬性 -->
    <bean id="propertyDemo1" class="cn.cbb.property.PropertyDemo1">
        <constructor-arg name="userName" value="小碼"></constructor-arg>
    </bean>
    package cn.cbb.property;
    
    public class PropertyDemo1 {
    
        private String userName;
    
        public PropertyDemo1(String userName) {
            this.userName = userName;
        }
        
        public void test1() {
            System.out.println("userName通過有參構造註入值為:"+userName);
        }
    }

spring註入對象類型屬性(重點

  • 首先,準備service類和dao類
  • 其次,要在service總得到dao對象,具體實現:
    • 在service中把dao作為類型屬性
    • 生成dao類型屬性的set方法
      package cn.cbb.ioc;
      
      public class UserService {
          //定義dao類型屬性
          private UserDao userDao;
          //生成set方法,在service中得到dao對象,就可以調用dao中的方法
          public void setUserDao(UserDao userDao) {
              this.userDao = userDao;
          }
      
          public void add() {
              System.out.println("service add ...");
              userDao.add();
          }
      }
    • 配置文件關系
      <!-- 註入對象類型的屬性 -->
      <!-- 配置service和dao對象 -->
      <bean id="userDao" class="cn.cbb.ioc.UserDao"></bean>
      <bean id="userService" class="cn.cbb.ioc.UserService">
          <!-- 註入dao對象:
              name屬性值:service中的屬性名稱,對象類型屬性就不要寫value了,用ref屬性:dao配置bean的id值
          -->
          <property name="userDao" ref="userDao"></property>
      </bean>

P命名空間註入(不常用,了解即可)

package cn.cbb.property;

public class Person {

    private String pname;

    public void setPname(String pname) {
        this.pname = pname;
    }
    
    public void testP() {
        System.out.println("P名稱空間註入pname值為"+pname);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    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">

    <!-- P名稱空間註入 -->
    <bean id="person" class="cn.cbb.property.Person" p:pname="小張"></bean>
</beans>

spring註入復雜數據

  • 數組
  • list集合
  • map集合
  • properties類型(鍵值對文件)
    package cn.cbb.property;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    
    public class Animal {
    
        private String[] arrs;
        private List<String> list;
        private Map<String,String> map;
        private Properties properties;
        
        public void setArrs(String[] arrs) {
            this.arrs = arrs;
        }
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
        
        public void testAnimal() {
            System.out.println("復雜數據註入arrs:"+arrs);
            System.out.println("復雜數據註入list:"+list);
            System.out.println("復雜數據註入map:"+map);
            System.out.println("復雜數據註入properties:"+properties);
        }
    }
    <!-- 註入復雜類型屬性值 -->
    <bean id="animal" class="cn.cbb.property.Animal">
        <!-- 數組 -->
        <property name="arrs">
            <list>
                <value>小王</value>
                <value>小李</value>
                <value>小張</value>
            </list>
        </property>
        <!-- list -->
        <property name="list">
            <list>
                <value>奧迪</value>
                <value>寶馬</value>
                <value>奔馳</value>
            </list>
        </property>
        <!-- map -->
        <property name="map">
            <map>
                <entry key="aa" value="lucy"></entry>
                <entry key="bb" value="lili"></entry>
                <entry key="cc" value="tom"></entry>
            </map>
        </property>
        <!-- properties -->
        <property name="properties">
            <props>
                <prop key="driverclass">com.mysql.jdbc.Driver</prop>
                <prop key="username">root</prop>
            </props>
        </property>
    </bean>

IOC和DI區別

  • IOC:控制反轉,把對象的創建交給spring進行配置管理;
  • DI:依賴註入,向類中屬性中設置值;
  • 關系:依賴註入不能單獨存在,需要在IOC的基礎之上錸完成操作。

spring整合web項目原理???

  • 加載spring核心配置文件
    //1、加載spring配置文件,根據配置創建對象
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");

    new對象,功能可以實現,但是效率太低!

  • 解決思路:把加載配置文件和創建對象的過程,放在服務器啟動的時候來完成。
  • 實現原理
    • ServletContext對象(服務器啟動後,項目中唯一一個對象)
    • 監聽器(監聽ServletContext對象在什麽時候創建)
    • 具體使用:
      • 在服務器啟動的時候,為每個項目創建一個ServletContext對象;
      • 使用監聽器監聽ServletContext對象創建時間;
      • 監聽到ServletContext對象創建的時候,加載spring配置文件,然後把配置文件配置的對象進行創建;
      • 把創建出來的對象放到ServletContext域對象中(setAttribute方法)
      • 獲取對象時,到ServletContext域中通過getAttribute方法獲取;

Spring框架[一]——spring概念和ioc入門(ioc操作xml配置文件)