1. 程式人生 > 實用技巧 >Spring簡介和配置

Spring簡介和配置

1. spring概述

1.1 Spring是什麼(理解)

Spring是分層的 Java SE/EE應用 full-stack 輕量級開源框架,以 IoC(Inverse Of Control:反轉控制)和 AOP(Aspect Oriented Programming:面向切面程式設計)為核心。

提供了展現層 SpringMVC和持久層 Spring JDBCTemplate以及業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,逐漸成為使用最多的Java EE 企業應用開源框架

1.2 Spring發展歷程 (瞭解)

Rod Johnson ( Spring 之父)

2017 年
9 月份釋出了 Spring 的最新版本 Spring5.0
通用版(GA)

1.3 Spring的優勢(理解)

方便解耦,簡化開發

AOP 程式設計的支援

宣告式事務的支援

方便程式的測試

1.4 Spring的體系結構(瞭解)

2. spring快速入門

2.1 Spring程式開發步驟

①匯入 Spring 開發的基本包座標

②編寫 Dao 介面和實現類

③建立 Spring 核心配置檔案

④在 Spring 配置檔案中配置 UserDaoImpl

⑤使用 Spring 的 API 獲得 Bean 例項

2.2 匯入Spring開發的基本包座標

<properties>
	<spring.version>5.0.5.RELEASE</spring.version>
</properties>
<!--匯入spring的context座標,context依賴core、beans、expression-->
<dependencies> 
    <dependency>  
        <groupId>org.springframework</groupId> 
        <artifactId>spring-context</artifactId> 
        <version>${spring.version}</version>
    </dependency>
</dependencies>

2.3 編寫Dao介面和實現類

public interface UserDao {  
    public void save();
}

public class UserDaoImpl implements UserDao {  
        @Override  
        public void save() {
        	System.out.println("UserDao save method running....");
	}
}

2.4 建立Spring核心配置檔案

在類路徑下(resources)建立applicationContext.xml配置檔案

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

2.5 在Spring配置檔案中配置UserDaoImpl

<?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">
   <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
</beans>

2.6 使用Spring的API獲得Bean例項

@Test
public void test1(){
		ApplicationContext applicationContext = new  
             ClassPathXmlApplicationContext("applicationContext.xml");
             UserDao userDao = (UserDao) applicationContext.getBean("userDao");   				 userDao.save();
 }

3. Spring配置檔案

3.1 Bean標籤基本配置

用於配置物件交由Spring 來建立。

預設情況下它呼叫的是類中的無參建構函式,如果沒有無參建構函式則不能建立成功。

基本屬性:

id:Bean例項在Spring容器中的唯一標識

class:Bean的全限定名稱

3.2 Bean標籤範圍配置

scope:指物件的作用範圍,取值如下:

取值範圍 說明
singleton 預設值,單例的
prototype 多例的
request WEB 專案中,Spring 建立一個 Bean 的物件,將物件存入到 request 域中
session WEB 專案中,Spring 建立一個 Bean 的物件,將物件存入到 session 域中
global session WEB 專案中,應用在 Portlet 環境,如果沒有 Portlet 環境那麼globalSession 相當於 session

1)當scope的取值為singleton時

​ Bean的例項化個數:1個

​ Bean的例項化時機:當Spring核心檔案被載入時,例項化配置的Bean例項

​ Bean的生命週期:

物件建立:當應用載入,建立容器時,物件就被建立了

物件執行:只要容器在,物件一直活著

物件銷燬:當應用解除安裝,銷燬容器時,物件就被銷燬了

2)當scope的取值為prototype時

​ Bean的例項化個數:多個

​ Bean的例項化時機:當呼叫getBean()方法時例項化Bean

物件建立:當使用物件時,建立新的物件例項

物件執行:只要物件在使用中,就一直活著

物件銷燬:當物件長時間不用時,被 Java 的垃圾回收器回收了

3.3 Bean生命週期配置

init-method:指定類中的初始化方法名稱

destroy-method:指定類中銷燬方法名稱

3.4 Bean例項化三種方式

1) 使用無參構造方法例項化

​ 它會根據預設無參構造方法來建立類物件,如果bean中沒有預設無參建構函式,將會建立失敗

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

2) 工廠靜態方法例項化

​ 工廠的靜態方法返回Bean例項

public class StaticFactoryBean {
    public static UserDao createUserDao(){    
    return new UserDaoImpl();
    }
}
<bean id="userDao" class="com.itheima.factory.StaticFactoryBean" 
      factory-method="createUserDao" />

3) 工廠例項方法例項化

​ 工廠的非靜態方法返回Bean例項

public class DynamicFactoryBean {  
	public UserDao createUserDao(){        
		return new UserDaoImpl(); 
	}
}
<bean id="factoryBean" class="com.itheima.factory.DynamicFactoryBean"/>
<bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao"/>

3.5 Bean的依賴注入入門

①建立 UserService,UserService 內部在呼叫 UserDao的save() 方法

public class UserServiceImpl implements UserService {
	@Override
	public void save() {
         ApplicationContext applicationContext = new 
                 ClassPathXmlApplicationContext("applicationContext.xml");       	           UserDao userDao = (UserDao) applicationContext.getBean("userDao");	
          userDao.save();
 	}
 }

②將 UserServiceImpl 的建立權交給 Spring

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>

③從 Spring 容器中獲得 UserService 進行操作

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
userService.save();

3.6 Bean的依賴注入概念

依賴注入(Dependency Injection):它是 Spring 框架核心 IOC 的具體實現。

在編寫程式時,通過控制反轉,把物件的建立交給了 Spring,但是程式碼中不可能出現沒有依賴的情況。

IOC 解耦只是降低他們的依賴關係,但不會消除。例如:業務層仍會呼叫持久層的方法。

那這種業務層和持久層的依賴關係,在使用 Spring 之後,就讓 Spring 來維護了。

簡單的說,就是坐等框架把持久層物件傳入業務層,而不用我們自己去獲取

3.7 Bean的依賴注入方式

①構造方法

​ 建立有參構造

public class UserServiceImpl implements UserService {
@Override
public void save() {
ApplicationContext applicationContext = new 
                 ClassPathXmlApplicationContext("applicationContext.xml");       UserDao userDao = (UserDao) applicationContext.getBean("userDao");    
          userDao.save();
    }
 }

​ 配置Spring容器呼叫有參構造時進行注入

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">      		   	<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

②set方法

​ 在UserServiceImpl中新增setUserDao方法

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;  
        } 
    @Override    
    public void save() {      
   		 userDao.save();
	}
}

​ 配置Spring容器呼叫set方法進行注入

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"/>
</bean>

set方法:P名稱空間注入

​ P名稱空間注入本質也是set方法注入,但比起上述的set方法注入更加方便,主要體現在配置檔案中,如下:

​ 首先,需要引入P名稱空間:

xmlns:p="http://www.springframework.org/schema/p"

其次,需要修改注入方式

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-
 ref="userDao"/>

3.8 Bean的依賴注入的資料型別

上面的操作,都是注入的引用Bean,處了物件的引用可以注入,普通資料型別,集合等都可以在容器中進行注入。

注入資料的三種資料型別

普通資料型別

引用資料型別

集合資料型別

其中引用資料型別,此處就不再贅述了,之前的操作都是對UserDao物件的引用進行注入的,下面將以set方法注入為例,演示普通資料型別和集合資料型別的注入。

Bean的依賴注入的資料型別

(1)普通資料型別的注入

public class UserDaoImpl implements UserDao {
private String company;
    private int age;
    public void setCompany(String company) {
        this.company = company;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void save() {
        System.out.println(company+"==="+age);
        System.out.println("UserDao save method running....");   
    }
}

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="company" value="傳智播客"></property>
    <property name="age" value="15"></property>
</bean>

(2)集合資料型別(List)的注入

public class UserDaoImpl implements UserDao {
	private List<String> strList;
	public void setStrList(List<String> strList) {
		this.strList = strList;
	}
	public void save() {
        System.out.println(strList);
        System.out.println("UserDao save method running....");
	}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="strList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
            <value>ccc</value>
        </list>
    </property>
</bean>

(3)集合資料型別(List)的注入

public class UserDaoImpl implements UserDao {
	private List<User> userList;
	public void setUserList(List<User> userList) {
	this.userList = userList;  
 }
public void save() {
	System.out.println(userList);
	System.out.println("UserDao save method running....");
	}
}
<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="userList">
        <list>
            <bean class="com.itheima.domain.User"/>
            <bean class="com.itheima.domain.User"/>
            <ref bean="u1"/>
            <ref bean="u2"/>       
        </list>
    </property>
</bean>

(4)集合資料型別( Map<String,User> )的注入

public class UserDaoImpl implements UserDao {
    private Map<String,User> userMap;
    public void setUserMap(Map<String, User> userMap) {
    this.userMap = userMap;
    }    
public void save() {      
	System.out.println(userMap);
	System.out.println("UserDao save method running....");
	}
}
<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="userMap">
        <map>            
            <entry key="user1" value-ref="u1"/>
            <entry key="user2" value-ref="u2"/>
        </map>
    </property>
</bean>

(5)集合資料型別(Properties)的注入

public class UserDaoImpl implements UserDao {
    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
	public void save() {
		System.out.println(properties);
		System.out.println("UserDao save method running....");
	}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
    <property name="properties">
        <props>
            <prop key="p1">aaa</prop>
            <prop key="p2">bbb</prop> 
            <prop key="p3">ccc</prop>
        </props>
    </property>
</bean>

3.9 引入其他配置檔案(分模組開發)

實際開發中,Spring的配置內容非常多,這就導致Spring配置很繁雜且體積很大,所以,可以將部分配置拆解到其他配置檔案中,而在Spring主配置檔案通過import標籤進行載入

<import resource="applicationContext-xxx.xml"/>

4. spring相關API

4.1 ApplicationContext的繼承體系

applicationContext:介面型別,代表應用上下文,可以通過其例項獲得 Spring 容器中的 Bean 物件

4.2 ApplicationContext的實現類

1)ClassPathXmlApplicationContext

​ 它是從類的根路徑下載入配置檔案 推薦使用這種

2)FileSystemXmlApplicationContext

​ 它是從磁碟路徑上載入配置檔案,配置檔案可以在磁碟的任意位置。

3)AnnotationConfigApplicationContext

​ 當使用註解配置容器物件時,需要使用此類來建立 spring 容器。它用來讀取註解。

4.3 getBean()方法使用

public Object getBean(String name) throws BeansException {  
	assertBeanFactoryActive();   
	return getBeanFactory().getBean(name);
}
public <T> T getBean(Class<T> requiredType) throws BeansException {   			    	assertBeanFactoryActive();
	return getBeanFactory().getBean(requiredType);
}

其中,當引數的資料型別是字串時,表示根據Bean的id從容器中獲得Bean例項,返回是Object,需要強轉。

當引數的資料型別是Class型別時,表示根據型別從容器中匹配Bean例項,當容器中相同型別的Bean有多個時,則此方法會報錯

getBean()方法使用

ApplicationContext applicationContext = new 
            ClassPathXmlApplicationContext("applicationContext.xml");
  UserService userService1 = (UserService) applicationContext.getBean("userService");
  UserService userService2 = applicationContext.getBean(UserService.class);