Spring4入門之第一章IOC和DI

Spring4入門之第一章

Spring的概述

Spring的概述

  • 什麼是Spring

    Spring框架是Java平臺的一個開源的全棧(Full-stack)應用程序框架和控制反轉(IOC)容器實現,一般被直接稱爲 Spring。該框架的一些核心功能理論上可用於任何 Java 應用,但 Spring 還爲基於java企業版平臺構建的 Web 應用提供了大量的拓展支持。雖然 Spring 沒有直接實現任何的編程模型,但它已經在 Java 社區中廣爲流行,基本上完全代替了企業級JavaBeans(EJB)模型。

  • Spring:SE/EE開發的一站式框架。

    • 一站式框架:有EE開發的每一層解決方案。
    • WEB層 :SpringMVC
    • Service層 :Spring的Bean管理,Spring聲明式事務
    • DAO層 :Spring的Jdbc模板,Spring的ORM模塊
  • 爲什麼學習Spring

在這裏插入圖片描述

Spring的入門(IOC XMl方式)

  • IOC: Inversion of Control(控制反轉)。將對象的創建權反轉給(交給)Spring。

  • 下載Spring的開發包

    https://blog.csdn.net/SYJ_1835_NGE/article/details/89415506

  • Spring的開發包

    在這裏插入圖片描述

    docs :Spring的開發規範和API

    libs :Spring的開發的jar和源碼

    schema :Spring的配置文件的約束

  • 創建web項目,引入jar包(紅框內爲必須部分)

在這裏插入圖片描述

  • 傳統方式和將控制權交給Spring管理的區別

    假設一個場景:Service層調用Dao層的代碼實現某個功能

    • 傳統的方式:

      //創建一個接口
      public interface UserDao {
      	public void save();
      }
      //-------------------------------
      //創建一個實現類
      public class UserDaoImpl implements UserDao {
      	@Override
      	public void save() {
      		System.out.println("UserDaoImpl執行了。。。。");
      	}
      }
      

      在進行某功能實現的時候我們可以直接調用,但是,如果要求在Dao的是實現方式上,要求使用Hibernate實現和數據庫的交互,我們需要修改源代碼,顯然是不合理的。

在這裏插入圖片描述

  • Spring方式實現

    要想使用Spring框架去管理我們的實現類,我們需要去創建一個配置文件一般以applicationContext.xml進行命名(但不是必須的)

    在applicationContext.xml文件中的一些注意的細節:

    引入schema約束:在spring-framework-4.2.4\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html,在最下面,裏面有多種schema約束

    the beans 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">
    
    
    </beans>
    

    關於在Eclipse中Spring約束提示問題:

    對bean進行配置

    <!-- Spring IOC的入門配置 -->
    <bean id="userDao" class="com.syj.spring.demo1.UserDaoImpl" />
    <bean id="userDaoHibernate" class="com.syj.spring.demo1.UserDaoHibernateImpl" />
    

    測試類:

    @Test
    	/**
    	 * Sring的IOC方式
    	 */
    	public void demo2() {
    		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    		UserDao userDao = (UserDao) applicationContext.getBean("userDao");
    		UserDao userDaoHibernate = (UserDao) applicationContext.getBean("userDaoHibernate");
    		userDaoHibernate.save();
    		userDao.save();
    	}
    

IOC和DI的區別和聯繫

  • IOC:控制反轉,將對象的創建權反轉給了Spring

    • DI:依賴注入,前提必須有IOC的環境,Spring管理這個類的時候將類的依賴的屬性注入(設置)進來。
  • 面向對象的時候

    • 依賴

      Class A{}
      //B依賴於A
      Class B{
      	public void xxx(A a){}
      }
      
    • 繼承:is a

      Class A{}
      Class B extends A{}
      
    • 聚合:has a

      根據緊密程度分:

      一個人必須有一個腦袋

      一個籃球隊有沒有中鋒都可以打比賽

  • 依賴注入的簡單演示

    public class UserDaoImpl implements UserDao {
        //爲name屬性進行賦值
    	private String name;
    	public void setName(String name) {
    		this.name = name;
    	}
    	@Override
    	public void save() {
    		System.out.println("UserDaoImpl執行了。。。。" + name);
    	}
    }
    

    我們只需要在配置文件中添加一段配置即可(不需要修改源碼)

    <bean id="userDao" class="com.syj.spring.demo1.UserDaoImpl" >
    		<property name="name" value="孫悟空" />
    </bean>
    

Spring的工廠類

  • 首先記住一個圖。Spring工程類的結構圖

在這裏插入圖片描述

  • ApplicationContext繼承BeanFactory

    • BeanFactory:老版本的工廠類

      BeanFactory:調用getBean的時候,纔會生成類的實例

    • ApplicationContext:新版本的工廠類

      ApplicationContext:加載配置文件的時候,就會將Spring管理的類都實例化

      ApplicationContext有兩個實現類

      • ClassPathXmlApplicationContext :加載類路徑下的配置文件
      • FileSystemXmlApplicationContext :加載文件系統下的配置文件

Spring中的Bean

Bean的相關配置

  • bean標籤的id和name的配置

    id :使用了約束中的唯一約束。裏面不能出現特殊字符的。

    name :沒有使用約束中的唯一約束(理論上可以出現重複的,但是實際開發不能出現的)。裏面可以出現特殊字符。

    <bean name=”/user” class=””/>
    
  • Bean的生命週期的配置

    init-method :Bean被初始化的時候執行的方法

    destroy-method :Bean被銷燬的時候執行的方法(Bean是單例創建,工廠關閉)

  • Bean的作用範圍的配置(重點)

    scope — > Bean的作用範圍

    scope取值 描述
    singleton 默認的,Spring會採用單例模式創建這個對象
    prototype 多例模式。(Struts2和Spring整合一定會用到)
    request 應用在web項目中,Spring創建這個類以後,將這個類存入到request範圍中。
    session 應用在web項目中,Spring創建這個類以後,將這個類存入到session範圍中。
    globalsession 應用在web項目中,必須在porlet環境下使用。但是如果沒有這種環境,相對於session。(登錄騰訊之後旗下的子項目qq空間等不需要再進行登錄)

Bean的管理(XML方式)

  • Spring的Bean的實例化方式(瞭解)

    Bean已經都交給Spring管理,Spring創建這些類的時候,有幾種方式:

    1. 無參構造方法的方式(默認)
    public class Bean1 {
    	public Bean1() {
    		super();
    		System.out.println("Bean1的無參數的構造方法執行了...");
    	}
    }
    //----------applicationContext.xml配置------------------
    <bean  id="bean1" class="com.syj.spring.demo2.Bean1" ></bean>
    
    1. 靜態工廠實例化的方式
     public class Bean2Factory {
     	public static Bean2 createBean2() {
     		System.out.println("Bean2Factory中方法執行了...");
     		return new Bean2();
     	}
     }
     //----------applicationContext.xml配置------------------
      <bean  id="bean2Factory" class="com.syj.spring.demo2.Bean2Factory" factory-method="createBean2" ></bean>
    
    1. 實例工廠實例化的方式
      public class Bean3Factory {
      	public Bean3 createBean3() {
      		System.out.println("Bean3Factory中方法執行了...");
      		return new Bean3();
      	}
      }
      //----------applicationContext.xml配置------------------
      <bean  id="bean3Factory" class="com.syj.spring.demo2.Bean3Factory" ></bean>
      <bean id="bean3"  factory-bean="bean3Factory" factory-method="createBean3" ></bean>
    

Spring的屬性注入

在這裏插入圖片描述

  • 構造方法的方式注入普通屬性

    public class Car {
    	/*
    	 * 屬性注入(構造方式)
    	 */
    	private String name;
    	private double price;
    
    	public Car(String name, double price) {
    		super();
    		this.name = name;
    		this.price = price;
    	}
    }
    //----------applicationContext.xml配置------------------
    <bean   id="car" class="com.syj.spring.demo3.Car" >
    			<constructor-arg name="name"  value="寶馬" />
    			<constructor-arg name="price"  value="800000" />
    </bean>
    
  • 構造方法的方式注入對象屬性

    public class Employee {
    	private String name;
    	private Car car;
    
    	public Employee(String name, Car car) {
    		super();
    		this.name = name;
    		this.car = car;
    	}
    }	
    //----------applicationContext.xml配置------------------
    <bean   id="employee" class="com.syj.spring.demo3.Employee" >
    			<constructor-arg name="name"  value="張三" />
    			<constructor-arg name="car"  ref="car" />
    </bean>
    
  • set方法的普通屬性注入

    public class Car2 {
    	/*
    	 * 屬性注入(構造方式)
    	 */
    	private String name;
    	private double price;
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void setPrice(double price) {
    		this.price = price;
    	}
    //----------applicationContext.xml配置------------------
    <bean  id="car2" class="com.syj.spring.demo3.Car2" >
    			<property name="name" value="奔馳" />
    			<property name="price" value="1000000" />
    </bean>
    
  • set方法的對象引用的屬性注入

    public class Employee2 {
    	private String name;
    	private Car2 car2;
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void setCar2(Car2 car2) {
    		this.car2 = car2;
    	}
    }
    //----------applicationContext.xml配置------------------
    <bean  id="employee2" class="com.syj.spring.demo3.Employee2" >
    			<property name="name" value="李四" />
    			<property name="car2" ref="car2" />
    </bean>
    
  • p命名空間的屬性注入

xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"<!-- 增加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名稱空間

<!-- p命名空間的屬性注入======================= -->
		<bean id="car2"  class="com.syj.spring.demo3.Car2" p:name="大衆" p:price="300000"  ></bean>
  • SpEL的屬性注入(Spring3.0以後)

    Spring Expression Language,Spring的表達式語言。

    語法: #{SpEL}

    public class CarInfo {
    	private String name;
    	public String getName() {
    		return "電車";
    	}
    	public double calculatorPrice() {
    		return Math.random() * 3000;
    	}
    }
    //----------applicationContext.xml配置------------------
    <!--  SpEL的屬性注入(Spring3.0以後)可以調用方法-->
    <bean  id="carinfo" class="com.syj.spring.demo3.CarInfo" ></bean>
    
    <bean  id="car2" class="com.syj.spring.demo3.Car2" >
        <property name="name" value="#{carinfo.name}" />
        <property name="price" value="#{carinfo.calculatorPrice()}" />
    </bean>
    
    <bean  id="employee2" class="com.syj.spring.demo3.Employee2" >
        <property name="name" value="#{'李四'}" />
        <property name="car2" value="#{car2}" />
    </bean>
    

集合類型的屬性注入

配置:

public class CollectionBean {
	private String[] strs;
	private List<String> list;
	private Set<String> set;
	private Map<String, String> map;
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
	public void setSet(Set<String> set) {
		this.set = set;
	}
	public void setList(List<String> list) {
		this.list = list;
	}
	public void setStrs(String[] strs) {
		this.strs = strs;
	}
	@Override
	public String toString() {
		return "CollectionBean [strs=" + Arrays.toString(strs) + ", list=" + list + ", set=" + set + ", map=" + map
				+ "]";
	}
}
//----------applicationContext.xml配置------------------
<!-- 複雜類型的屬性注入=============== -->
		<bean  id="collectionBean" class="com.syj.spring.demo4.CollectionBean" >
			<property name="strs">
				<list>
					<value>張三</value>
					<value>李四</value>
					<value>王五</value>
					
				</list>
			</property>
			<property name="list">
				<list>
					<value>111</value>
					<value>222</value>
					<value>333</value>
				</list>
			</property>
			<property name="set">
				<set>
					<value>aaa</value>
					<value>bbb</value>
					<value>ccc</value>
				</set>
			</property>
			<property name="map">
				<map>
					<entry key="張三" value="奧迪" ></entry>
					<entry key="李四" value="奔馳" ></entry>
					<entry key="王五" value="寶馬" ></entry>
				</map>
			</property>
		</bean>
		

分模塊開發

  • 在加載配置文件的時候,加載多個

    @Test
    	// 分模塊開發(多個參數)
    	public void demo1() {
    		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml",
    				"applicationContext2.xml");
    		CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");
    		System.out.println(collectionBean);
    	}
    
  • 在一個配置文件中引入多個配置文件

    <!-- 在其中一個引入另外一個-->
    <import resource="applicationContext2.xml"/>
    

Spring小練習(模擬保存用戶關係)

  • 傳統的保存客戶關係,是在web層new出CustomerServiceImpl對象,然後Service層的。最後Service層調用Dao層。每次在new對象的時候,當需求發生改變的時候我們就需要修改源代碼。極其的不合適,於是我們可以通過Spring爲我們管理Service層和Dao層的創建,

  • Action實現調用由Spring管理的Service層和在Service注入的Dao層

  • 此項目前臺已經基本完成,只需要簡單引入即可進行後臺的測試

    鏈接:https://pan.baidu.com/s/1ph1NQ2HDbl3PPqpnJGDTkQ 密碼:7oia

    主要引入紅色部位

在這裏插入圖片描述

步驟:

  • 創建web項目,引入相應的jar包

  • 包結構

在這裏插入圖片描述

  • 創建配置文件Struts2的(web.xml,struts.xml)Spring的(applicationContext.xml)和日誌的(log4j.properties)

  • 對頁面進行修改menu.jsp的【新增客戶】按鈕

在這裏插入圖片描述

  • 創建action

    com.syj.web.action.CustomerAction

    public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
    	private Customer customer = new Customer();
    
    	public String saveUI() {
    		System.out.println("CustomerAction的saveUI方法執行了。。。");
    		return "saveUI";
    	}
    
    
    	@Override
    	public Customer getModel() {
    		return customer;
    	}
    
    }
    
    

    struts.xml配置

    <package name="crm" extends="struts-default" namespace="/" >
    		<action name="customer_*" class="com.syj.web.action.CustomerAction" method="{1}"  >
    			<result  name="saveUI" >/jsp/customer/add.jsp</result>
    		</action>
    </package>
    
  • 創建Service層和Dao層,全都交給Spring管理

    CustomerServiceImpl.java

    public class CustomerServiceImpl implements CustomerService {
    	private CustomerDao customerDao;
    
    	public void setCustomerDao(CustomerDao customerDao) {
    		this.customerDao = customerDao;
    	}
    
    	@Override
    	public void save(Customer customer) {
    		System.out.println("CustomerServiceImpl的save執行了。。。");
    		customerDao.save(customer);
    	}
    }
    

    CustomerDaoImpl.java

    public class CustomerDaoImpl implements CustomerDao {
    
    	@Override
    	public void save(Customer customer) {
    		System.out.println("CustomerDaoImpl的save方法執行了。。。");
    		System.out.println(customer);
    	}
    
    }
    

    對Spring的applicationContext.xml文件進行配置

    <!-- 將CustomerService交給Spring進行管理 -->
    	<bean id="customerService" class="com.syj.service.CustomerServiceImpl" >
    			<!-- 在Service層注入CustomerDaoImpl屬性 -->
    		<property name="customerDao"  ref="customerDao" />
    	</bean>
    	<!-- 將CustomerDao交給Spring進行管理 -->
    	<bean id="customerDao" class="com.syj.dao.CustomerDaoImpl" >
    	</bean>
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章