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

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() {
              //一、加載spring配置文件,根據配置建立對象
              ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
              //二、獲得配置建立的對象
              User user = (User) context.getBean("user");
              System.out.println(user);
              user.add();
          }
      }

配置文件無提示問題

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

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

bean實例化三種方式

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

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

      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核心配置文件
    //一、加載spring配置文件,根據配置建立對象
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");

    new對象,功能能夠實現,可是效率過低!web

  • 解決思路:把加載配置文件和建立對象的過程,放在服務器啓動的時候來完成。
  • 實現原理
    • ServletContext對象(服務器啓動後,項目中惟一一個對象)
    • 監聽器(監聽ServletContext對象在何時建立)
    • 具體使用:
      • 在服務器啓動的時候,爲每一個項目建立一個ServletContext對象;
      • 使用監聽器監聽ServletContext對象建立時間;
      • 監聽到ServletContext對象建立的時候,加載spring配置文件,而後把配置文件配置的對象進行建立;
      • 把建立出來的對象放到ServletContext域對象中(setAttribute方法)
      • 獲取對象時,到ServletContext域中經過getAttribute方法獲取;
相關文章
相關標籤/搜索