spring框架搭建第二天
文章目錄
- 1. Spring的DI
- 1.1 使用構(gòu)造器注入
- 1.2 使用set方法注入
- 1.4 對于集合等復(fù)雜類型的注入
- 2. 基于注解的DI
- 2.1 使用@Component注解創(chuàng)建對象
- 2.2 使用@Autowired自動注入對象
- 2.2 @Qualifier
- 3. 一個IOC案例
- 3.1 基于xml配置文件
- 3.2 基于注解
- 3.3 完全基于注解的配置
- 4.Spring的IOC總結(jié)
- 4.1 對象交由IOC管理
1. Spring的DI
前面提到過,Spring的IOC(控制反轉(zhuǎn))有兩種方式,一種是常見的依賴注入(Dependency Injection),另外的一種是依賴查找(Dependency Lookup)。
在Spring中,依賴關(guān)系的管理都交由spring來維護(hù),當(dāng)前類需要用到其他類的對象,由spring為我們提供,我們只需要在配置文件中說明即可。
這種依賴關(guān)系的維護(hù)叫做依賴注入。
依賴注入的類型有:
- 基本類型和String
- 其他的bean類型(在配置文件中或者注解中配置過的bean)
- 復(fù)雜類型/集合類型
注入的方式有三種:
1.1 使用構(gòu)造器注入
前面在學(xué)習(xí)6.Spring對bean的管理中,在6.1.1 使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建bean中,遇到一個問題。當(dāng)類的構(gòu)造器被重寫后(入?yún)⒏淖兞?#xff09;,如果繼續(xù)用<bean></bean>標(biāo)簽穿件,則會報錯。
現(xiàn)在可以通過<bean></bean>標(biāo)簽下的constructor-arg標(biāo)簽使用重寫后的構(gòu)造器注入。
假如現(xiàn)在AccountServiceImpl的構(gòu)造器如下:
那么它的bean的配置文件為:
<bean id="accountService" class="com.ssm.service.impl.AccountServiceImpl"><constructor-arg type="java.lang.String" value="你叫什么名字"></constructor-arg><constructor-arg type="java.lang.String" value="你好啊"></constructor-arg><constructor-arg name="age" value="18"></constructor-arg><constructor-arg name="brithday" ref="now"></constructor-arg></bean><bean id="now" class="java.util.Date"></bean>詳細(xì)了解<constructor-arg></constructor-arg>。
它是位于bean標(biāo)簽的內(nèi)部的,用來使用構(gòu)造器初始化一個bean的。相當(dāng)于調(diào)用指定類的構(gòu)造器。既然要使用構(gòu)造器實例化某個對象。那么需要傳入一些參數(shù)(無參構(gòu)造器直接使用默認(rèn)的bean配置即可)。為了傳入?yún)?shù),有一下問題:
- 如何定位到某個參數(shù)?
- 如何往參數(shù)傳值?
總的來說,spring怎么知道往哪個參數(shù)傳入哪個值。
如何定位到某個參數(shù)?
constructor-arg標(biāo)簽有三個屬性:type、index、name
- type:要注入數(shù)據(jù)的數(shù)據(jù)類型,同時也是構(gòu)造器入?yún)⒌臄?shù)據(jù)類型。如果構(gòu)造器有多個同類型的屬性,則依照配置循序依次注入。
- index:屬性的順序
- name:屬性的名稱
如何往參數(shù)傳值?
- value:用于提供基本數(shù)據(jù)類型 以及基本數(shù)據(jù)的封裝
- ref:前面的例子可以看出,他是傳入引用類型的變量
小結(jié)
使用構(gòu)造器注入的特點:
優(yōu)勢:
可以根據(jù)類的構(gòu)造器傳入指定值,比默認(rèn)方式靈活。
缺點:
必須要按照構(gòu)造器的參數(shù)來傳值。
1.2 使用set方法注入
使用property標(biāo)簽完成set方式注入
//AccountServiceImpl2片段public void setName(String name) {this.name = name;}public void setName1(String name1) {this.name1 = name1;}public void setAge(Integer age) {this.age = age;}public void setBrithday(Date brithday) {this.brithday = brithday;} <bean id="accountService2" class="com.ssm.service.impl.AccountServiceImpl2"><property name="name" value="使用set方式"></property><property name="age" value="20"></property><property name="brithday" ref="now"></property></bean>| name | 定位到set方法,若方法名為setName,則name值為name |
| value | 同上,用于提供基本數(shù)據(jù)類型 以及基本數(shù)據(jù)的封裝 |
| ref | 同上,傳入引用類型的變量 |
注意:
使用set方式注入,其實還是用無參構(gòu)造器實例化對象。若沒有無參構(gòu)造器,仍會報前面提到的問題。
1.4 對于集合等復(fù)雜類型的注入
private String[] myStr;private List<String> myList;private Map<String, String> myMap;private Properties myProps;public void setMyStr(String[] myStr) {this.myStr = myStr;}public void setMyList(List<String> myList) {this.myList = myList;}public void setMyMap(Map<String, String> myMap) {this.myMap = myMap;}public void setMyProps(Properties myProps) {this.myProps = myProps;}bean的內(nèi)部
<property name="myStr"><array><value>AAA</value><value>BBB</value></array></property><property name="myList"><list><value>AAA</value><value>BBB</value></list></property><property name="myMap"><map><entry key="testA" value="value1"></entry><entry key="testB"><value>value2</value></entry></map></property><property name="myProps"><props><prop key="key1">hahahha</prop><prop key="key2">lalala</prop></props></property>注入方式有
對于String[],List,Set類型的變量
使用<array>,</list>,<set>方式注入。
對于map,props類型等映射關(guān)系變量
使用<map>,<prop>方式注入。
2. 基于注解的DI
前面我們學(xué)習(xí)的所有的DI都是基于xml配置文件的。如果一個項目有幾十上百的bean。那么它的配置文件將會顯得十分冗長龐大。使用注解就能解決這個問題。基于這一點,基于注解的DI應(yīng)該與基于配置文件的DI的作用應(yīng)該是一樣的,只是實現(xiàn)方式不一樣。
回顧前面的知識,我們可以總結(jié)出基于xml配置文件實現(xiàn)的功能總共分為四類:
那么注解應(yīng)該也能實現(xiàn)上述四種功能
2.1 使用@Component注解創(chuàng)建對象
使用注解創(chuàng)建對象有一下幾步:
為類AccountServiceImpl添加注解
//使用@Component創(chuàng)建對象(無參構(gòu)造器),對象名(id)為accountService,若不配置對象,則對象名為accountServiceImpl @Component(value = "accountService") public class AccountServiceImpl implements IAccountService { }在bean.xml中配置context的名稱空間與約束。
前面使用的配置
其中 xmlns是xml命名空間的意思,而xmlns:xsi是指xml所遵守的標(biāo)簽規(guī)范。
因為配置掃描的標(biāo)簽不在beans的約束中,而在一個名為context的名稱空間和約束中,所以需要引入。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--告訴Spring在創(chuàng)建容器需要掃描的包為com.ssm--><context:component-scan base-package="com.ssm"></context:component-scan> </beans>用上述方法創(chuàng)建對象時,容器會把包中的所有對象實例化。不管有沒有被使用。
2.2 使用@Autowired自動注入對象
- @Controller:一般用于表現(xiàn)層
- @Service:一般用于業(yè)務(wù)層
- @Repository:一般用于持久層
以上三個注解作用于屬性與@Component基本一樣,有點類似于父類-子類的關(guān)系。
@Autowired先根據(jù)數(shù)據(jù)類型IAccountDao注入對象,如果容器中沒有,報錯;如果有唯一一個,成功;
如果有多個,在根據(jù)變量名稱accountDao注入,如果沒有,報錯;如果有唯一一位,成功;
2.2 @Qualifier
按照類中注入的基礎(chǔ)上,在按照名稱注入。在給類成員注入時不能單獨使用,但是在給方法參數(shù)注入時可以。
3. 一個IOC案例
創(chuàng)建一個account表
CREATE TABLE `account` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`money` float(255,0) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;然后創(chuàng)建一個工程,能夠?qū)υ摫韺崿F(xiàn)CRUD操作。
主要有
要求有分為業(yè)務(wù)層和持久層。還有junit測試單元
3.1 基于xml配置文件
基于xml配置的IOC案例
3.2 基于注解
基于注解的IOC案例
存在一個問題,還是需要xml配置bean。
3.3 完全基于注解的配置
前面的配置中,AccountServiceImpl和AccountDaoImpl可以通過注解加到容器中。
| accountServiceImpl | com.ssm.service.impl.AccountServiceImpl | 通過@Service加到Spring核心容器中 |
| accountDao | com.ssm.dao.impl.AccountDaoImpl | 通過@Repository(value = “accountDao”)加入 |
| runner(多例) | org.apache.commons.dbutils.QueryRunner | bean.xml |
| dataSource | com.mchange.v2.c3p0.ComboPooledDataSource | bean.xml |
測試類中,核心容器創(chuàng)建過程還是
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
現(xiàn)在配置一種完全舍棄bean.xml的方式。
這時需要兩個注解
- @Configuration:指定當(dāng)前類是一個配置類
- @Companent:通過注解指定spring在創(chuàng)建容器時需要掃描的包
整個類配置如下
其中涉及的注解
@Configuration:
@ComponentScan
@Bean
@Scope
4.Spring的IOC總結(jié)
回顧前面的學(xué)習(xí),我們發(fā)現(xiàn)使用Spring的IOC一個最重要的目的是解耦。
它的解耦方式是:IOC容器管理所有的對象,其他對象想使用某個對象,就需要通過對象id來獲取。
4.1 對象交由IOC管理
Spring創(chuàng)建Bean的三種方式
使用默認(rèn)的構(gòu)造函數(shù)(無參即可)創(chuàng)建
調(diào)用B類的方法來創(chuàng)建A類的對象,主要針對第三方j(luò)ar包。
<!--先實例化B類(instanceFactory)--> <bean id="instanceFactory" class="com.ssm.factory.InstanceFactory"></bean> <!--調(diào)用B類的getAccountService方法,創(chuàng)建一個A類的對象--> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>調(diào)用B類的靜態(tài)方法創(chuàng)建A類對象,無需實例化B類
<!--使用B類的靜態(tài)方法創(chuàng)建對象A--> <bean id="accountService" class="com.ssm.factory.StaticFactory" factory-method="getAccountService"></bean>總結(jié)
以上是生活随笔為你收集整理的spring框架搭建第二天的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring框架搭建第一天
- 下一篇: 用tensorflow实现yolov3