spring框架搭建第二天
文章目錄
- 1. Spring的DI
- 1.1 使用構造器注入
- 1.2 使用set方法注入
- 1.4 對于集合等復雜類型的注入
- 2. 基于注解的DI
- 2.1 使用@Component注解創建對象
- 2.2 使用@Autowired自動注入對象
- 2.2 @Qualifier
- 3. 一個IOC案例
- 3.1 基于xml配置文件
- 3.2 基于注解
- 3.3 完全基于注解的配置
- 4.Spring的IOC總結
- 4.1 對象交由IOC管理
1. Spring的DI
前面提到過,Spring的IOC(控制反轉)有兩種方式,一種是常見的依賴注入(Dependency Injection),另外的一種是依賴查找(Dependency Lookup)。
在Spring中,依賴關系的管理都交由spring來維護,當前類需要用到其他類的對象,由spring為我們提供,我們只需要在配置文件中說明即可。
這種依賴關系的維護叫做依賴注入。
依賴注入的類型有:
- 基本類型和String
- 其他的bean類型(在配置文件中或者注解中配置過的bean)
- 復雜類型/集合類型
注入的方式有三種:
1.1 使用構造器注入
前面在學習6.Spring對bean的管理中,在6.1.1 使用默認構造函數創建bean中,遇到一個問題。當類的構造器被重寫后(入參改變了),如果繼續用<bean></bean>標簽穿件,則會報錯。
現在可以通過<bean></bean>標簽下的constructor-arg標簽使用重寫后的構造器注入。
假如現在AccountServiceImpl的構造器如下:
那么它的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>詳細了解<constructor-arg></constructor-arg>。
它是位于bean標簽的內部的,用來使用構造器初始化一個bean的。相當于調用指定類的構造器。既然要使用構造器實例化某個對象。那么需要傳入一些參數(無參構造器直接使用默認的bean配置即可)。為了傳入參數,有一下問題:
- 如何定位到某個參數?
- 如何往參數傳值?
總的來說,spring怎么知道往哪個參數傳入哪個值。
如何定位到某個參數?
constructor-arg標簽有三個屬性:type、index、name
- type:要注入數據的數據類型,同時也是構造器入參的數據類型。如果構造器有多個同類型的屬性,則依照配置循序依次注入。
- index:屬性的順序
- name:屬性的名稱
如何往參數傳值?
- value:用于提供基本數據類型 以及基本數據的封裝
- ref:前面的例子可以看出,他是傳入引用類型的變量
小結
使用構造器注入的特點:
優勢:
可以根據類的構造器傳入指定值,比默認方式靈活。
缺點:
必須要按照構造器的參數來傳值。
1.2 使用set方法注入
使用property標簽完成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 | 同上,用于提供基本數據類型 以及基本數據的封裝 |
| ref | 同上,傳入引用類型的變量 |
注意:
使用set方式注入,其實還是用無參構造器實例化對象。若沒有無參構造器,仍會報前面提到的問題。
1.4 對于集合等復雜類型的注入
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的內部
<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類型等映射關系變量
使用<map>,<prop>方式注入。
2. 基于注解的DI
前面我們學習的所有的DI都是基于xml配置文件的。如果一個項目有幾十上百的bean。那么它的配置文件將會顯得十分冗長龐大。使用注解就能解決這個問題。基于這一點,基于注解的DI應該與基于配置文件的DI的作用應該是一樣的,只是實現方式不一樣。
回顧前面的知識,我們可以總結出基于xml配置文件實現的功能總共分為四類:
那么注解應該也能實現上述四種功能
2.1 使用@Component注解創建對象
使用注解創建對象有一下幾步:
為類AccountServiceImpl添加注解
//使用@Component創建對象(無參構造器),對象名(id)為accountService,若不配置對象,則對象名為accountServiceImpl @Component(value = "accountService") public class AccountServiceImpl implements IAccountService { }在bean.xml中配置context的名稱空間與約束。
前面使用的配置
其中 xmlns是xml命名空間的意思,而xmlns:xsi是指xml所遵守的標簽規范。
因為配置掃描的標簽不在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在創建容器需要掃描的包為com.ssm--><context:component-scan base-package="com.ssm"></context:component-scan> </beans>用上述方法創建對象時,容器會把包中的所有對象實例化。不管有沒有被使用。
2.2 使用@Autowired自動注入對象
- @Controller:一般用于表現層
- @Service:一般用于業務層
- @Repository:一般用于持久層
以上三個注解作用于屬性與@Component基本一樣,有點類似于父類-子類的關系。
@Autowired先根據數據類型IAccountDao注入對象,如果容器中沒有,報錯;如果有唯一一個,成功;
如果有多個,在根據變量名稱accountDao注入,如果沒有,報錯;如果有唯一一位,成功;
2.2 @Qualifier
按照類中注入的基礎上,在按照名稱注入。在給類成員注入時不能單獨使用,但是在給方法參數注入時可以。
3. 一個IOC案例
創建一個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;然后創建一個工程,能夠對該表實現CRUD操作。
主要有
要求有分為業務層和持久層。還有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 |
測試類中,核心容器創建過程還是
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
現在配置一種完全舍棄bean.xml的方式。
這時需要兩個注解
- @Configuration:指定當前類是一個配置類
- @Companent:通過注解指定spring在創建容器時需要掃描的包
整個類配置如下
其中涉及的注解
@Configuration:
@ComponentScan
@Bean
@Scope
4.Spring的IOC總結
回顧前面的學習,我們發現使用Spring的IOC一個最重要的目的是解耦。
它的解耦方式是:IOC容器管理所有的對象,其他對象想使用某個對象,就需要通過對象id來獲取。
4.1 對象交由IOC管理
Spring創建Bean的三種方式
使用默認的構造函數(無參即可)創建
調用B類的方法來創建A類的對象,主要針對第三方jar包。
<!--先實例化B類(instanceFactory)--> <bean id="instanceFactory" class="com.ssm.factory.InstanceFactory"></bean> <!--調用B類的getAccountService方法,創建一個A類的對象--> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>調用B類的靜態方法創建A類對象,無需實例化B類
<!--使用B類的靜態方法創建對象A--> <bean id="accountService" class="com.ssm.factory.StaticFactory" factory-method="getAccountService"></bean>總結
以上是生活随笔為你收集整理的spring框架搭建第二天的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring框架搭建第一天
- 下一篇: 用tensorflow实现yolov3