Spring_IOC&DI

Spring_IoC&DI


## 1. spring概述

1.1 Spring是什麼(理解)

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

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

1.2 Spring發展歷程 (瞭解)

Rod Johnson ( Spring 之父)express

2017年 9月份發佈了  Spring的最新版本 Spring5.0 通用版(GA)編程

1.3 Spring的優點(理解)

方便解耦,簡化開發api

AOP 編程的支持session

聲明式事務的支持app

方便程序的測試框架

1.4 Spring的體系結構(瞭解)

2. spring快速入門

2.1 Spring程序開發步驟

①導入 Spring 開發的基本包座標dom

②編寫 Dao 接口和實現類ide

③建立 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>    
    //bean標籤:在Spring的容器中 聲明一個Bean對象
    //id屬性:爲bean類的惟一標識,不可重複
    //class屬性:建立的bean全類名

</beans>

2.6 使用Spring的API得到Bean實例

@Test
public void test1(){

        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) app.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) 工廠靜態方法實例化
    建立一個工廠類(StaticFactoryBean),在工廠類中 包含靜態而且返回對象的方法(createUserDao)
​ 工廠的靜態方法返回Bean實例

public class StaticFactoryBean {
    public static UserDao createUserDao(){    
    return new UserDaoImpl();
    }
}

在ApplicationContext.xml配置文件中,class屬性聲明 靜態工廠類 的全類名,而且添加 factory-method 屬性,屬性值爲工廠類中的靜態方法名
當Spring讀取配置文件時,會根據 factory-method 屬性,調用靜態方法,返回UserDaoImpl對象

<bean id="userDao" class="com.itheima.factory.StaticFactoryBean" factory-method="createUserDao" />
    //等價於:UserDao userDao = StaticFactoryBean.createUserDao();

3) 工廠實例方法實例化
    建立一個工廠類(DynamicFactoryBean),在工廠類中 包含非靜態而且返回對象的方法(createUserDao)
​ 工廠的非靜態方法返回Bean實例

public class DynamicFactoryBean {  
	public UserDao createUserDao(){        
		return new UserDaoImpl(); 
	}
}

    當工廠類的方法爲非靜態時,那麼就不能直接進行調用,就須要先讓Spring容器建立工廠類的對象,
再經過 factory-bean , factory-method 屬性進行返回

<bean id="factoryBean" class="com.itheima.factory.DynamicFactoryBean"/>
    //等價於:factoryBean = new DynamicFactoryBean;
<bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao"/>
    //等價於:UserDao userDao = factoryBean.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() {
        private UserDao userDao;

        public userServiceImpl() {
        }
        public userServiceImpl(UserDao userDao) {
            this.userDao = userDao;
        }

        public void seva() {
            userDao.test();
        }
    }
 }

​ 配置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="XXX"></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);
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息