一、IOC創建對象的三種方式
1、使用無參構造器,也是默認的創建方式
2、使用有參構造器
1)第一種:下標賦值 : <constructor-arg index="0" value="zhangsan"/>
2)第二種:類型賦值: <constructor-arg type="java.lang.String" value="zhangsan"/> 不能處理兩個參數類型一樣的情況
3) 第三種:直接通過參數名賦值 <constructor-arg name="name" value="zhangsan"/>
3、利用工廠創建對象
靜態工廠:工廠本身不需要創建對象;通過靜態方法調用,對象=工廠類.工廠方法名();
使用方法:
class: 指定工廠全類名
factory-method: 指定工廠方法
constructor-arg: 可以為方法傳參
<bean id="airPlane01" class="com.lxy.factory.AirPlaneStaticFactory" factory-method="getAirPlane">
<constructor-arg name="name" value="波音747"/>
</bean>
實例工廠:工廠本身需要創建對象
工廠類 工廠對象 = new 工廠類();
工廠對象.工廠方法名();
區別就是 一個是靜態的方法 一個不是 靜態方法可以直接調用,不是靜態需要先new
使用方法
1、先配置出實例工廠對象 <bean id="airPlaneInstaceFactory" class="com.lxy.factory.AirPlaneInstanceFactory"/>
2、配置我們要創建的AirPlane使用哪個工廠創建
1)、factory-bean指定使用哪個工廠創建
2)、factory-method指定使用哪個工廠方法
<bean id="airPlane02" class="com.lxy.pojo.AirPlane" factory-bean="airPlaneInstaceFactory" factory-method="getAirPlane">
<constructor-arg name="name" value="波音787"/>
</bean>
實現了FactoryBean的接口類是Spring可以認識的工廠類 自己寫的工廠類需要繼承FactoryBean
Spring會自動的調用工廠方法創建實例
1、編寫一個FactoryBean的實現類
2、在Spring配置文件中進行注冊
<bean id="myFactoryBeanImpl" class="com.lxy.factory.MyFactoryBeanImpl"/>
二、不同類型的賦值/注入方式
1、普通賦值
<bean id="hello" class="com.lxy.pojo.Hello">
<property name="str" value="Spring"/> 通過value
</bean>
2、對象賦值
<bean id="userServiceImpl" class="com.lxy.service.UserServiceImpl">
<property name="userDao" ref="mysqlImpl"/> 通過ref
<bean/>
3、bean注入 (以下<bean id=""><bean>等省略,只寫了注入方式)
<property name="address" ref="hello"/>
4、數組注入
<property name="books">
<array>
<value>西游記</value>
<value>紅樓夢</value>
<value>三國演義</value>
<value>水滸傳</value>
</array>
</property>
5、list 注入(set同理 只是把標簽換成<set>)
1) list中添加普通值
<property name="hobbies">
<list>
<value>敲代碼</value>
<value>聽音樂</value>
<value>打台球</value>
</list>
</property>
2) list中添加對象 (所有其他容器類型都可以通過這種方式進行對象添加)
<property name="bookList">
<list>
<bean id="book01" class="com.lxy.pojo.Book" p:bookName="三體"/>
<ref bean="book01"/>
</list>
</property>
6、map注入
1)不可引用注入
<property name="card">
<map>
<entry key="1" value="身份證"/>
<entry key="2" value="校園卡"/>
<entry key="3" value="醫保卡"/>
</map>
</property>
2)可以引用注入(list、set也可以通過這種方式進行可以引用注入)
<util:map id="map">
<entry key="1" value="元素1"/>
<entry key="2" value="元素2"/>
<entry key="3" value="元素3"/>
</util:map>
7、null注入(主要用在想把某個已經賦值的屬性再賦值為null)
<property name="wife">
<null/>
</property>
8、properties注入
<property name="info">
<props>
<prop key="學號">1111</prop>
<prop key="姓名">張三</prop>
</props>
</property>
9、繼承<bean>的配置信息(如果一個<bean>設置有abstract=true 那么這個bean只能被繼承,不能實例化)
<bean id="book02" class="com.lxy.pojo.Book" parent="book01" >
<property name="price" value="100"/>
</bean>
三、通過命名空間注入值 (c命名空間和p命名空間不能直接使用,需要導入xml約束)
1)、p命名空間注入,可以直接注入屬性的值: property
singleton: 單例模式(spring默認機制)
1、在容器啟動完成之前就已經創建好對象,保存在容器中
2、任何獲取都是獲取之前創建好的對象
導入p命名空間 xmlns:p="http://www.springframework.org/schema/p"
bean id="user" class="com.lxy.pojo.User" p:name="張三" p:age="24" scope="singleton"
2)、c命名空間注入,通過構造器注入: constructor-args
prototype: 原型模式:每次從容器中get的時候,都會產生一個新的對象
1、容器啟動默認不會去創建多實例bean
2、獲取的時候創建bean
3、每次獲取都會創建一個新的實例對象
導入p命名空間 xmlns:p="http://www.springframework.org/schema/c"
<bean id="user2" class="com.lxy.pojo.User" c:age="24" c:name="李四" scope="prototype"/>
四、通過SpEL(Spring Expression Language)賦值
<bean id="student" class="com.lxy.pojo.Student">
<property name="name" value="lisi"/>
</bean>
<bean id="book" class="com.lxy.pojo.Book">
<property name="bookName" value="三體"/>
<property name="price" value="100"/>
</bean>
<bean id="user" class="com.lxy.pojo.User">
<!--字面量 #{} 可以在#{}里面直接寫運算表達式-->
<property name="salary" value="#{12345.97*12}"/>
<!--引用其他bean的某個屬性值-->
<property name="studentName" value="#{student.name}" />
<!--引用其他bean-->
<property name="book" value="#{book}"/>
<!--調用靜態方法--> #{T(全類名).方法名}
<property name="id" value="#{T(java.util.UUID).randomUUID().toString().substring(0,5)}"/>
<!--調用非靜態方法-->
<property name="age" value="#{book.getPrice()}"/>
</bean>
五、自動裝配
自動裝配:僅限於對自定義類型的屬性有效 前提是容器中必須有相對應的組件
byName: 會自動在容器上下文中查找,和自己對象set方法后面的值對應的bean id 注意:不能夠區分大小寫,id都用小寫
byType: 會自動在容器上下文中查找,和自己對象屬相同的bean (可以省略id)注意:需要保證類型全局唯一
constructor: 按照有參構造器進行賦值
1、先按照有參構造器參數的類型進行裝配,沒有裝配null
2、如果找到的類型有多個,參數的名作為id繼續匹配
如果屬性是一個容器 例如list<book> 那么自動裝配會把所有的book的bean裝配進去
<bean id="people" class="com.lxy.pojo.People" autowire="byName">
<property name="name" value="張三"/>
</bean>
也可以通過注解的方式 在屬性上添加@Autowired
總之,自動裝配的前提是spring容器中有對應的組件,才會把該組件的值裝配/賦值到要自動裝配的屬性上去。沒有就不賦值