Spring4.IoC容器bean配置詳解
阿新 • • 發佈:2019-01-02
之前在有簡單的配置過bean,在bean的配置中有多種配置方式,下面一一介紹。
bean的配置方式
1.通過全類名(反射)
通過全類名方式
配置Bean
id:標識容器中的Bean,id屬性唯一
注意:當我們初始化ioc容器的時候,ioc容器會例項化單例的bean。
這樣配置是不會有問題的因為,有預設無參建構函式,如果沒有無參構造會出以下異常
獲取ioc容器的Bean
功過getBean()方法來獲取ioc容器的Bean。
getBean("id") 通過Bean的id標識來獲取bean
getBean(class) 通過類的class來獲取
通過第二種方式來獲取Bean需要注意
當我們使用第二種方式來獲取Bean,getBean(Car.class);這樣程式不知道你要獲取那個Bean.所有就會出現異常。
注入方式
屬性注入,屬性注入是使用set方法來注入
建構函式注入,通過建構函式注入
工廠注入,一般不用
屬性注入例子
如果需要指定引用資料型別的時候,就需要使用ref屬性。ref="id"
建構函式注入例子
我們現在有一個構造方法
也可以使用index與type屬性來之名是第幾個引數,或引數型別是什麼。如果使用index屬性配置引數,需要注意index的屬性下標時從0開始的。
Bean的初始化依賴
當我初始化某個Bean時,在此之前必須已經初始化了另一個Bean
使用外部屬性檔案
Spring提供了一個PropertyPlaceholderConfigurer的BeanFactory後置處理器,這個處理器可以將使用者配置Bean的部分內容移到屬性檔案,使用${var}來獲取值。
bean的配置方式
1.通過全類名(反射)
2.通過工廠方法(靜態工廠方法&例項工廠方法)
3.FactoyBean
通過全類名方式
配置Bean
<bean id="Car" class="cc.badboy.entity.Car">
<property name="name" value="福特"/>
</bean>
class:全路徑必須提供無參建構函式id:標識容器中的Bean,id屬性唯一
注意:當我們初始化ioc容器的時候,ioc容器會例項化單例的bean。
這樣配置是不會有問題的因為,有預設無參建構函式,如果沒有無參構造會出以下異常
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Car' defined in class path resource [ApplicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [cc.badboy.entity.Car]: No default constructor found; nested exception is java.lang.NoSuchMethodException: cc.badboy.entity.Car.<init>() Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Car' defined in class path resource [ApplicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [cc.badboy.entity.Car]: No default constructor found; nested exception is java.lang.NoSuchMethodException: cc.badboy.entity.Car.<init>() at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1110) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1055) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at Test.main(Test.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [cc.badboy.entity.Car]: No default constructor found; nested exception is java.lang.NoSuchMethodException: cc.badboy.entity.Car.<init>() at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1103) ... 18 more Caused by: java.lang.NoSuchMethodException: cc.badboy.entity.Car.<init>() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.getDeclaredConstructor(Class.java:2178) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ... 19 more
獲取ioc容器的Bean
功過getBean()方法來獲取ioc容器的Bean。
getBean("id") 通過Bean的id標識來獲取bean
getBean(class) 通過類的class來獲取
通過第二種方式來獲取Bean需要注意
我的配置檔案是這樣寫的Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [cc.badboy.entity.Car] is defined: expected single matching bean but found 2: Car,Car1 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1031) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1088) at Test.main(Test.java:12) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
<bean id="Car" class="cc.badboy.entity.Car">
<property name="name" value="福特"/>
</bean>
<bean id="Car1" class="cc.badboy.entity.Car">
<property name="name" value="布加迪"/>
</bean>
可以看到,我配置了兩個Bean,但class屬性是同一個類。當我們使用第二種方式來獲取Bean,getBean(Car.class);這樣程式不知道你要獲取那個Bean.所有就會出現異常。
注入方式
屬性注入,屬性注入是使用set方法來注入
建構函式注入,通過建構函式注入
工廠注入,一般不用
屬性注入例子
<bean id="Car" class="cc.badboy.entity.Car">
<span style="color:#ff0000;"><property name="name" value="福特"/></span>
</bean>
上面紅色標記屬性注入,name屬性:表明屬性名;value屬性:表明屬性值。注意value屬性只能注入基本資料型別。如果需要指定引用資料型別的時候,就需要使用ref屬性。ref="id"
建構函式注入例子
我們現在有一個構造方法
public Car(String name) {
System.out.println("汽車品牌為:" + name);
}
配置Bean <bean id="Car" class="cc.badboy.entity.Car">
<span style="color:#ff0000;"><constructor-arg name="name" value="福特"/></span>
</bean>
上面紅色標記為建構函式中的引數,name屬性:表明引數列表的中引數名;value屬性:引數值也可以使用index與type屬性來之名是第幾個引數,或引數型別是什麼。如果使用index屬性配置引數,需要注意index的屬性下標時從0開始的。
如果value屬性需要賦值特殊值,例如< >要知道,簡括號在xml中是有特殊意義的,所以需要使用<![CDATA[值]]>
集合屬性賦值例子
配置集合屬性兩種方式
第一種方式
<bean id="Car" class="cc.badboy.entity.Car">
<constructor-arg name="name">
<value><![CDATA[福特]]></value>
</constructor-arg>
</bean>
<bean id="person" class="cc.badboy.entity.Person">
<property name="cars">
<list>
<ref bean="Car"></ref>
</list>
</property>
</bean>
第二種方式 <bean id="Car" class="cc.badboy.entity.Car">
<constructor-arg name="name">
<value><![CDATA[福特]]></value>
</constructor-arg>
</bean>
<util:list id="list">
<ref bean="Car"/>
</util:list>
<bean id="person" class="cc.badboy.entity.Person">
<property name="cars" ref="list"/>
</bean>
Map集合屬性例子 <bean id="person" class="cc.badboy.entity.Person">
<property name="cars">
<map>
<entry key="AA" value-ref="Car"></entry>
</map>
</property>
</bean>
第二種方式 <bean id="Car" class="cc.badboy.entity.Car">
<constructor-arg name="name">
<value><![CDATA[福特]]></value>
</constructor-arg>
</bean>
<util:map id="map">
<entry key="AA" value-ref="Car"/>
</util:map>
<bean id="person" class="cc.badboy.entity.Person">
<property name="cars" ref="map"/>
</bean>
給Properties類屬性複製 <bean id="person" class="cc.badboy.entity.Person">
<property name="properties">
<props>
<prop key="userName">root</prop>
<prop key="passWord">123456</prop>
</props>
</property>
</bean>
Bean繼承配置 <bean id="Car" class="cc.badboy.entity.Car">
<constructor-arg name="name">
<value><![CDATA[福特]]></value>
</constructor-arg>
</bean>
<bean id="person" class="cc.badboy.entity.Person" <span style="color:#ff0000;">parent="Car"</span>>
</bean>
parent表明要繼承那個Bean的配置,子Bean也可以覆蓋父Bean中的配置。Bean的初始化依賴
當我初始化某個Bean時,在此之前必須已經初始化了另一個Bean
<bean id="Car" class="cc.badboy.entity.Car">
<constructor-arg name="name">
<value><![CDATA[福特]]></value>
</constructor-arg>
</bean>
<bean id="person" class="cc.badboy.entity.Person" depends-on="Car">
</bean>
使用外部屬性檔案
Spring提供了一個PropertyPlaceholderConfigurer的BeanFactory後置處理器,這個處理器可以將使用者配置Bean的部分內容移到屬性檔案,使用${var}來獲取值。
<!-- 匯入屬性檔案 -->
<context:property-placeholder location="屬性檔案"/>
<bean id="Car" class="cc.badboy.entity.Car">
<constructor-arg name="name">
<value>${鍵}</value>
</constructor-arg>
</bean>