Bean配置信息是Bean的元數據信息,它由一下4個方面組成:java
Bean元數據信息在Spring容器中的內部對應物是一個個BeanDefinition造成的Bean註冊表,Spring實現了Bean元數據信息內部表示和外部定義之間的解耦。正則表達式
Spring1.0僅支持基於XML的配置,Spring2.0新增基於註解配置的支持,Spring3.0新增基於Java類配置的支持,Spring4.0則新增給予Groovy動態語言配置的支持。
spring
<?xml version="1.0" encoding="utf-8" ?> <beans (1)xmlns="http://www.springframework.org/schema/beans" (2)xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:(3)context=(4)"http://www.springframework.org/schema/context" xsi:(5)schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
xmlns:namespace-prefix="namespaceURI"
,其中namespace-prefix爲自定義前綴,只要在這個XML文檔中保證前綴不重複便可;namespaceURI是這個前綴對應的XML Namespace的定義。xsi:schemaLocation定義了XML Namespace和對應的 XSD(Xml Schema Definition)文檔的位置的關係。它的值由一個或多個URI引用對組成,兩個URI之間以空白符分隔(空格和換行都可)。第一個URI是定義的 XML Namespace的值,第二個URI給出Schema文檔的位置,Schema處理器將從這個位置讀取Schema文檔,該文檔的targetNamespace必須與第一個URI相匹配。例如:數據庫
<beans xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
這裏表示Namespace爲http://www.springframework.or...://www.springframework.org/schema/context/spring-context.xsd。express
<!--id不能夠配置多個: context.getBean("myBean1, myBean2")--> <bean class="com.ankeetc.spring.MyBean" id="myBean1, myBean2"/> <!--context.getBean("myBean1") == context.getBean("myBean2")--> <bean class="com.ankeetc.spring.MyBean" name="myBean1, myBean2"/>
,
分割;id和name能夠都爲空,此時則能夠經過獲取全限定類名來獲取Bean。public class MyBeanFactory { public static MyBean createMyBean() { return new MyBean(); } }
<bean id="myBean" class="com.ankeetc.spring.MyBeanFactory" factory-method="createMyBean"/>
public class MyBeanFactory { public MyBean createMyBean() { return new MyBean(); } }
<bean id="myBeanFactory" class="com.ankeetc.spring.MyBeanFactory"/> <bean id="myBean" factory-bean="myBeanFactory" factory-method="createMyBean"/>
<beans>元素提供了一個default-autowire屬性能夠全局自動匹配,默認爲no。<bean>元素提供了一個指定自動裝配類型的autowire屬性,能夠覆蓋<beans>元素的default-autowire屬性,該屬性有以下選項:緩存
自動裝配類型 | 說明 |
---|---|
no | 顯式指定不使用自動裝配。 |
byName | 若是存在一個和當前屬性名字一致的 Bean,則使用該 Bean 進行注入。若是名稱匹配可是類型不匹配,則拋出異常。若是沒有匹配的類型,則什麼也不作。 |
byType | 若是存在一個和當前屬性類型一致的 Bean ( 相同類型或者子類型 ),則使用該 Bean 進行注入。byType 可以識別工廠方法,即可以識別 factory-method 的返回類型。若是存在多個類型一致的 Bean,則拋出異常。若是沒有匹配的類型,則什麼也不作。 |
constructor | 與 byType 相似,只不過它是針對構造函數注入而言的。若是當前沒有與構造函數的參數類型匹配的 Bean,則拋出異常。使用該種裝配模式時,優先匹配參數最多的構造函數。 |
default | 根據 Bean 的自省機制決定採用 byType 仍是 constructor 進行自動裝配。若是 Bean 提供了默認的構造函數,則採用 byType;不然採用 constructor 進行自動裝配。 |
<util:list></util:list> <util:set></util:set> <util:map></util:map>
<bean class="com.ankeetc.spring.MyBean" id="myBean"> <property name="prop" value="prop"/> </bean>
<bean class="com.ankeetc.spring.MyBean" id="myBean"> <constructor-arg type="java.lang.String" index="0" value="abc"/> <constructor-arg type="int" index="1" value="10"/> </bean>
<![CDATA[]]>
節或者轉義序列<ref>元素能夠經過如下三個屬性引用容器中的其餘Bean:session
<bean id="prop" class="com.ankeetc.spring.Prop"> <property name="value" value="1314"/> </bean> <bean id="myBean" class="com.ankeetc.spring.MyBean"> <property name="prop"> <!--內部Bean即便提供了id、name、scope也會被忽略--> <bean id="prop" class="com.ankeetc.spring.Prop"> <property name="value" value="520"/> </bean> </property> </bean>
<null/>
表明null值prop.value
,並且支持多層級聯屬性NullValueInNestedPathException
public class MyBean { // 必須初始化 private Prop prop = new Prop(); public Prop getProp() { return prop; } public void setProp(Prop prop) { this.prop = prop; } }
<bean id="myBean" class="com.ankeetc.spring.MyBean"> <property name="prop.value" value="1314"/> </bean>
<bean id="parentBean" class="com.ankeetc.spring.MyBean"> <property name="list"> <list> <value>1314</value> </list> </property> </bean> <bean id="myBean" class="com.ankeetc.spring.MyBean" parent="parentBean"> <property name="list"> <list merge="true"> <value>520</value> </list> </property> </bean>
類型 | 說明 |
---|---|
singleton | 在Spring IoC容器中僅存在一個Bean實例,Bean以單實例的方式存在 |
prototype | 每次從容器中調用Bean時,都返回一個新的實例 |
request | 每次HTTP請求都會建立一個新的Bean,該做用域僅適用於WebApplicationContext環境 |
session | 同一個HTTP session共享一個Bean,不一樣的HTTP session使用不一樣的Bean,該做用域僅適用於WebApplicationContext環境 |
globalSession | 同一個全局Session共享一個Bean,通常用於Portlet環境,該做用域僅適用於WebApplicationContext環境 |
見後續章節app
見後續章節ide
因爲實例化Bean的過程比較負責,可能須要大量的配置,這是採用編碼的方式多是更好的選擇。Spring提供了FactoryBean工廠類接口,用戶能夠實現該接口定製實例化Bean的邏輯。當配置文件中<bean>的class屬性配置的是FactoryBean的子類時,經過getBean()返回的不是FactoryBean自己,而是getObject()方法所返回的對象,至關因而FactoryBean#getObject()代理了getBean()方法。函數
T getObject() throws Exception;
:返回由FactoryBean建立的Bean實例,若是isSingleton()返回的是true,該實例會放到Spring容器的實例緩存池中。Class<?> getObjectType();
:返回該FactoryBean建立的Bean的類型boolean isSingleton();
:建立的Bean是singleton的仍是prototype/** * 實現,分割的方式配置 KFCCombo 屬性 */ public class KFCFactoryBean implements FactoryBean<KFCCombo> { private String prop; public String getProp() { return prop; } // 接受,分割的屬性設置信息 public void setProp(String prop) { this.prop = prop; } // 實例化KFCCombo public KFCCombo getObject() throws Exception { KFCCombo combo = new KFCCombo(); String[] props = prop.split(","); combo.setBurger(props[0]); combo.setDrink(props[1]); return combo; } public Class<?> getObjectType() { return KFCCombo.class; } // true則放進容器緩存池,false則每次都調用getObject()方法返回新的對象 public boolean isSingleton() { return false; } }
<bean id="combo" class="com.ankeetc.spring.KFCFactoryBean"> <property name="prop" value="ZingerBurger, PepsiCola"/> </bean>
@Component:在Bean的實現類上直接標註,能夠被Spring容器識別
@Repository:用於對DAO實現類進行標柱
@Service:用於對Service實現類進行標註
@Controller:用於對Controller實現類進行標註
Spring提供了一個context命名空間,用於掃描以註解定義Bean的類。
<!--生命context命名空間--> <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/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.ankeetc.spring"/> </beans>
**/*.class
,即基包下的全部類類別 | 示例 | 說明 |
---|---|---|
annotation | com.ankeetc.XxxAnnotation | 全部標註了XxxAnnotation的類。該類型採用目標類是否標誌了某個註解進行過濾。 |
assignable | com.ankeetc.XxService | 全部繼承或擴展XXXService的類。該類型採用目標類是否繼承或者擴展了某個特定類進行過濾 |
aspectj | com.ankeetc..*Service+ | 全部類名以Service結束的類及繼承或者擴展他們的類。該類型採用AspectJ表達式進行過濾 |
regex | com.ankeetc.auto..* | 全部com.ankeetc.auto類包下的類。該類型採用正則表達式根據目標類的類名進行過濾 |
custom | com.ankeetc.XxxTypeFilter | 採用XxxTypeFilter代碼方式實現過濾規則,該類必須實現org.springframework.core.type.TypeFilter接口 |
<!-- 僅掃描標註了@Controller註解的類--> <context:component-scan base-package="com.ankeetc.spring" use-default-filters="false"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
@Component public class KFCCombo { @Autowired private PepsiCola cola; @Autowired private Map<String, Cola> colaMap; @Autowired private List<ZingerBurger> burgerList; private ZingerBurger burger; @Autowired public void setBurger(@Qualifier(value = "zingerBurger") ZingerBurger burger) { this.burger = burger; } public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:/beans.xml"}); KFCCombo combo = context.getBean(KFCCombo.class); } } interface Cola {} @Order(value = 1) @Component class CocaCola implements Cola {} @Order(value = 2) @Component class PepsiCola implements Cola {} @Component(value = "zingerBurger") class ZingerBurger { }
public class Main { public static void main(String[] args) { // (1)能夠直接設置容器啓動要加載的類 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DaoConfig.class); // (2)能夠向容器中註冊新的類 ((AnnotationConfigApplicationContext) applicationContext).register(ServiceConfig.class); // (3)註冊了新的類要記得refresh ((AnnotationConfigApplicationContext) applicationContext).refresh(); } } @Configuration class DaoConfig { @Bean public String getStr() { return "1314"; } } @Configuration @Import(DaoConfig.class) // (4)能夠經過@Import將多個配置類組裝稱一個配置類 class ServiceConfig { }
標註了@Configureation的配置類自己也是一個bean,它能夠被Spring的<context:component-scan>掃描到。若是但願將此配置類組裝到XML配置文件中,經過XML配置文件啓動Spring容器,僅在XML文件中經過<context:component-scan>掃描到相應的配置類便可。
<context:component-scan base-package="com.ankeetc.spring" resource-pattern="Config.class"/>
在標註了@Configuration的配置類中,能夠經過@ImportResource引入XML配置文件。
@Configuration @ImportResource("classpath:beans.xml") public class Config { }