Spring簡介和配置

heima老師整理

 

spring概述

Spring是什麼

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

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

Spring發展歷程

Spring的優勢

方便解耦,簡化開發

通過 Spring 提供的 IoC容器,可以將對象間的依賴關係交由 Spring 進行控制,避免硬編碼所造成的過度耦合。用戶也不必再爲單例模式類、屬性文件解析等這些很底層的需求編寫代碼,可以更專注於上層的應用。

AOP 編程的支持

通過 SpringAOP 功能,方便進行面向切面編程,許多不容易用傳統 OOP 實現的功能可以通過 AOP 輕鬆實現

聲明式事務的支持

可以將我們從單調煩悶的事務管理代碼中解脫出來,通過聲明式方式靈活的進行事務管理,提高開發效率和質量

方便程序的測試

可以用非容器依賴的編程方式進行幾乎所有的測試工作,測試不再是昂貴的操作,而是隨手可做的事情。

方便集成各種優秀框架

Spring對各種優秀框架(StrutsHibernateHessianQuartz等)的支持。

降低 JavaEE API 的使用難度

SpringJavaEE API(如 JDBCJavaMail、遠程調用等)進行了薄薄的封裝層,使這些 API 的使用難度大爲降低。

Java 源碼是經典學習範例

Spring的源代碼設計精妙、結構清晰、匠心獨用,處處體現着大師對Java 設計模式靈活運用以及對 Java技術的高深造詣。它的源代碼無意是 Java 技術的最佳實踐的範例。

Spring的體系結構

spring快速入門

Spring程序開發步驟 

  1. 導入 Spring 開發的基本包座標
  2. 編寫 Dao 接口和實現類
  3. 創建 Spring 核心配置文件
  4. 在 Spring 配置文件中配置 UserDaoImpl
  5. 使用 Spring 的 API 獲得 Bean 實例

導入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>

編寫Dao接口和實現類

public interface UserDao {  
    public void save();
}

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

創建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>

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

使用Spring的API獲得Bean實例

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

Spring配置文件

Bean標籤基本配置 

用於配置對象交由Spring 來創建。

默認情況下它調用的是類中的無參構造函數,如果沒有無參構造函數則不能創建成功。

基本屬性:

  • id:Bean實例在Spring容器中的唯一標識
  • class:Bean的全限定名稱

Bean標籤範圍配置 

scope:指對象的作用範圍,取值如下: 

1當scope的取值爲singleton時

Bean的實例化個數:1個

Bean的實例化時機:當Spring核心文件被加載時,實例化配置的Bean實例

Bean的生命週期:

  • 對象創建:當應用加載,創建容器時,對象就被創建了
  • 對象運行:只要容器在,對象一直活着
  • 對象銷燬:當應用卸載,銷燬容器時,對象就被銷燬了

2)當scope的取值爲prototype時

Bean的實例化個數:多個

Bean的實例化時機:當調用getBean()方法時實例化Bean

  • 對象創建:當使用對象時,創建新的對象實例
  • 對象運行:只要對象在使用中,就一直活着
  • 對象銷燬:當對象長時間不用時,被 Java 的垃圾回收器回收了

Bean生命週期配置

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

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

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();

Bean的依賴注入概念

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

在編寫程序時,通過控制反轉,把對象的創建交給了 Spring,但是代碼中不可能出現沒有依賴的情況。IOC 解耦只是降低他們的依賴關係,但不會消除。例如:業務層仍會調用持久層的方法。

那這種業務層和持久層的依賴關係,在使用 Spring 之後,就讓 Spring 來維護了。簡單的說,就是坐等框架把持久層對象傳入業務層,而不用我們自己去獲取

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

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<String>)的注入

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<User>)的注入

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>

引入其他配置文件(分模塊開發)

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

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

spring相關API

ApplicationContext的繼承體系

  • applicationContext:接口類型,代表應用上下文,可以通過其實例獲得 Spring 容器中的 Bean 對象

ApplicationContext的實現類

1)ClassPathXmlApplicationContext 

​      它是從類的根路徑下加載配置文件 推薦使用這種

2)FileSystemXmlApplicationContext 

​      它是從磁盤路徑上加載配置文件,配置文件可以在磁盤的任意位置。

3)AnnotationConfigApplicationContext

​      當使用註解配置容器對象時,需要使用此類來創建 spring 容器。它用來讀取註解。

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有多個時,則此方法會報錯

ApplicationContext applicationContext = new 
            ClassPathXmlApplicationContext("applicationContext.xml");
  UserService userService1 = (UserService) applicationContext.getBean("userService");
  UserService userService2 = applicationContext.getBean(UserService.class);
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章