Spring入門1
在之前我們對象的創建都是我們自己new出來的,比如Student stu=new Student(),但是我們現在有了spring,我們將對象的創建的工作交給spring來處理。
那麼spring是怎麼創建對象的呢,創建對象之後有時保存在哪裏的呢?
不知道大家清不清楚反射的概念。spring就是利用反射來進行創建對象。
就是我們給定一個字符串,在spring這裏給定的字符串是你的類的全名(包括包名和類名),根據這個字符串可以創建對應類的對象,然後將創建好的對象以Map集合的形式保存下來。也就是以key和value的形式保存下來。
下面就是獲取spring的容器,然後根據id來創建對象。
獲取spring容器的IOC核心容器,並根據id獲取對象
這裏的IOC核心容器和之前工廠模式中將對象存入Map容器裏面是一樣的。
ApplicationContext的三個常用實現類:
ClassPathXmlApplicationContext:它可以加載類路徑下的配置文件,要求配置文件必須在類路徑下。(更 常用)不在的話,加載不了。
FileSystemXmlApplicationContext:它可以加載磁盤任意路徑下的配置文件(必須有訪問權限)
AnnotationConfigApplicationContext:它是用於讀取註解創建容器的。
核心容器ApplicationContext和BeanFactory兩個接口之間的區別:
ApplicationContext: 適用場景:單例對象使用
它在構建核心容器時,創建對象採取的策略是採用立即加載的方式。也就是說
只要一讀取完配置文件馬上就創建配置文件中配置的對象。
BeanFactory: 適用場景:多例對象使用
它在構建核心容器時,創建對象採取的策略是延遲加載的方式。也就是說
什麼時候根據id獲取對象了,什麼時候才真正的獲取對象。不是加載完文件之後立即創建對象
public static void main(String[] args)
{
//1.獲取核心容器對象
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");//這個寫入的路徑是類路勁下的路徑
//ApplicationContext ac=new FileSystemXmlApplicationContext("F:\\spring01\\src\\main\\resources\\bean.xml");
//這個寫的是全路徑
//2.根據id獲取bean對象
AccountService as= (AccountService) ac.getBean("accountService");
AccountDao adao= ac.getBean("accountDao",AccountDao.class);
// //上面兩種創建對象的方式都可以。
System.out.println(as);
System.out.println(adao);
//------------------BeanFactory-------------------------
// Resource resource=new ClassPathResource("bean.xml");
// BeanFactory factory=new XmlBeanFactory(resource);
// AccountService as= (AccountService) factory.getBean("accountService");
// System.out.println(as);
}
SpringBean入門2
把對象的創建交給spring來管理。
spring對bean的管理細節:
1.創建bean的三種方式
2.bean對象的作用範圍
3.bean對象的生命週期。
創建bean的三種方式
第一種方式:使用默認構造函數創建
在spring的配置文件中使用bean標籤,配以id和class屬性之後,且沒有其他屬性和標籤時。
採用的就是默認構造函數創建bean對象,如果此時類中沒有默認構造函數,則對象無法創建。
<bean id="accountService" class="bean.service.impl.AccountServiceImpl">
<bean id="accountDao" class="springioc.dao.impl.AccountDaoImpl"></bean>
第二種方式:使用普通工廠中的方法創建對象(使用某個類中的方法創建對象,並存入spring容器)
如果還是直接使用id的方法獲取對象的話,獲取的是工廠的對象,不是我們返回值的service對象。
所以如何獲得返回值的service對象,而不是工廠對象呢?
使用場景:當某個類中的某個方法的返回值是某個對象的時候或者使用某個方法創建對象的時候。
<bean id="instanceFactory" class="bean.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
上面accountService是我們真正要創建的對象,但是這個對象是使用某個類中的方法創建的,那麼我們要指定這個類的bean和這個類中創建這個對象的方法。
我們現在有一個instanceFactory對象,他是一個工廠,它裏面有方法可以爲我們創建service對象。
那麼我們需要定義一個service對象,那麼這個對象是如何來的呢。
是由id爲instanceFactory的工廠中的getAccountService方法來獲取的。
package bean.factory;/**
* Created by HongyongHan on 2020/3/28.
*/
import bean.service.AccountService;
import bean.service.impl.AccountServiceImpl;
/**
* @program: springbean
* @description:
* @author: HongyongHan
* @create: 2020-03-28 17:17
**/
/*
模擬一個工廠類,該類可能存在於jar包中的,我們無法通過修改源碼的方式來提供默認構造函數。
*/
public class InstanceFactory {
public AccountService getAccountService()
{
return new AccountServiceImpl();
}
}
第三種方式:使用靜態工廠中的靜態方法創建對象(使用某個類中的靜態方法創建對象,並存入spring容器)
使用場景:當某個類的某個方法是靜態方法的時候並且使用這個靜態方法創建對象。
<bean id="accountService" class="bean.factory.StaticFactory" factory-method="getAccountService"></bean>
package bean.factory;/**
* Created by HongyongHan on 2020/3/28.
*/
import bean.service.AccountService;
import bean.service.impl.AccountServiceImpl;
/**
* @program: springbean
* @description:
* @author: HongyongHan
* @create: 2020-03-28 17:17
**/
/*
模擬一個工廠類,該類可能存在於jar包中的,我們無法通過修改源碼的方式來提供默認構造函數。
*/
public class StaticFactory {
public static AccountService getAccountService()
{
return new AccountServiceImpl();
}
}
bean的作用範圍調整
默認是單例的。
bean標籤的scope屬性:
作用:用於指定bean的作用範圍
取值:常用的就是單例的和多例的
singleton:單例的(默認值)
prototype:多例。
request:作用於web應用的請求範圍
session:作用於web應用的會話範圍
global-session:作用於集羣環境的會話範圍(全局會話範圍),當不是集羣環境時,就是session
<bean id="accountService" class="bean.service.impl.AccountServiceImpl" scope="prototype"></bean>
bean對象的生命週期:
1.單例對象.
出生:當容器創建時對象出生
活着:只要容器還在,對象一直活着
死亡:容器銷燬,對象消亡
總結:單例對象的生命週期和容器相同.
2.多例對象:
出生:當我們使用對象時spring框架爲我們創建,是延遲創建對象
活着:對象只要是在使用過程中就一直活着
死亡:當對象長時間不用且沒有別的對象引用時,由java的垃圾回收器回收.
<bean id="accountService" class="bean.service.impl.AccountServiceImpl" scope="prototype" init-method="init" destroy-method="destroy">
</bean>
Spring入門3 spring中的依賴注入di
依賴注入:
Dependency Injection
IOC的作用:
降低程序間的耦合(依賴關係)
依賴關係的管理:以後都交給了spring來維護。
在當前類中需要用到其他類的對象,由spring爲我們提供,我們只需要在配置文件中說明
依賴關係的維護:
就稱爲依賴注入。
依賴注入:
能注入的數據:有三類:
基本類型和String
其他bean類型(在配置文件中活着註解配置過的bean)
複雜類型/集合類型
注入方式:有三種
第一種:使用構造函數提供
第二種:使用set方法提供。
第三種:使用註解提供。
<!--構造函數注入:開發中一般不用
使用標籤:constructor-arg
標籤出現的位置:bean標籤的內部
標籤中的屬性:
type:用於指定要注入的數據的數據類型。該數據類型也是構造函數某個或者某些參數的類型
<constructor-arg type="java.lang.String" value="test" >:這樣可以給type是string類型的注入test值。但是一般不獨立使用。
index:用於指定要注入的數據給構造函數中指定索引位置的參數賦值。索引的位置從0開始。
可以獨立使用,但是要記住每個索引是什麼類型。比較麻煩.
name:用於指定給構造函數中指定名稱的參數賦值。(常用)
=========以上三個用於指定給構造函數中哪個參數賦值==========
value:用於提供基本類型和String類型的數據
ref:用於指定其他的bean類型數據。它指的是在spring的IOC核心容器中出現過的bean對象。
優勢:
在獲取bean對象時,注入數據是必須的選擇,否則對象無法創建成功。
弊端:
改變了bean對象的實例化方式,使我們創建對象時,如果用不到這些數據,也必須提供。
-->
<bean id="accountService" class="springdi.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="test" ></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!--配置一個日期對象-->
<bean id="now" class="java.util.Date"></bean>
<!--set方法注入(常用)
涉及標籤:property
出現的位置:bean標籤的內部
標籤的屬性:
name:用於指定注入時所調用的set方法名稱xxx。就是之前名字是setXxx方法。
value:用於提供基本類型和String類型的數據
ref:用於指定其他的bean類型數據。它指的是在spring的IOC核心容器中出現過的bean對象。
優勢:創建對象時,沒有明確的限制,可以直接使用默認構造函數。
弊端:如果有某個成員必須有值,則獲取對象時有可能set方法沒有執行。
-->
<bean id="accountService2" class="springdi.service.impl.AccountServiceImpl2">
<property name="name" value="test"></property>
<property name="age" value="21"></property>
<property name="birthday" ref="now"></property>
</bean>
<!--複雜類型的注入(集合類型的注入)
用於給List結構集合注入的標籤:
list array set
用於給Map結構集合注入的標籤:
map props
結構相同,標籤可以互換。實際上記住兩組就可以了,list的和map的標籤。
-->
<bean id="accountService3" class="springdi.service.impl.AccountServiceImpl3">
<property name="myStrs">
<array>
<value>aaa</value>
<value>rrr</value>
<value>ayay</value>
</array>
</property>
<property name="myList">
<list>
<value>lll</value>
<value>iii</value>
<value>stst</value>
</list>
</property>
<property name="mySet">
<set>
<value>sss</value>
<value>eee</value>
<value>ttt</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="test" value="value"></entry>
<entry key="testBBB">
<value>BBB</value>
</entry>
</map>
</property>
<property name="myProps">
<props>
<prop key="testprop">ccc</prop>
<prop key="testBBB">BBB</prop>
</props>
</property>
</bean>