Spring Bean 配置三種方式:
- XML顯式配置
- Java中顯式配置
- 隱式Bean發(fā)現(xiàn)機(jī)制和自動(dòng)裝配。
隱式Bean發(fā)現(xiàn)機(jī)制
- @Compone(@Named 基本上等價(jià)) 聲明Bean
- @Compone("aaa")可以制定Bean id,默認(rèn)id為Bean的首字母小寫.
- @Comfiguration 聲明一個(gè)類為Java類,并用@ComponentScan開啟自動(dòng)發(fā)現(xiàn)機(jī)制,或在XML中<context:componect-scan base-package="包名">
- @ComponentScan 可以指定多個(gè)包名
@ComponentScan(basePackages = {"soundsfs","asdfs"})或者指定一個(gè)類,這Spring會(huì)去搜索該類所在的包@ComponentScan(basePackageClasses = CompactDisc.class),在每個(gè)包下聲明一個(gè)mark interface用于發(fā)現(xiàn)Bean。 - 對(duì)需要注入的類進(jìn)行@Autowired (@Inject 基本上等價(jià))進(jìn)行自動(dòng)裝配,這樣Spring就可以進(jìn)行搜索,從而設(shè)定符合要求的類進(jìn)行注入
- 如果自動(dòng)裝配的類不存在將會(huì)報(bào)錯(cuò)。
org.springframework.beans.factory.NoSuchBeanDefinitionException - 如果多個(gè)符合標(biāo)準(zhǔn)也會(huì)報(bào)錯(cuò)
org.springframework.beans.factory.NoUniqueBeanDefinitionException
Java顯式配置
- 聲明該Java類為配置類。@Configuration 表明該類為配置類。
- 在一個(gè)可以創(chuàng)建所需要類型實(shí)例的方法上@Bean 表面返回的該對(duì)象是需要注冊(cè)到Spring上下文中的Bean。和XML中的<Bean> 相同。
- @Bean(name="bean自定義Id")
@Bean
public CDPlayer clPlayer(){return new CDPlayer();}
- Spring會(huì)對(duì)這樣的方法調(diào)用進(jìn)行攔截,并不是每一次都是完全的調(diào)用,可以直接放回該方法的的實(shí)例.Spring中Bean默認(rèn)是單例的。
- Spring會(huì)對(duì)方法的參數(shù)進(jìn)行自動(dòng)裝配。
@Bean
public CDPlayer clPlayer(A a){return new B(a);}
XML顯式配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--聲明一個(gè)Bean 默認(rèn)id=soundsystem.SgtPeppers#0-->
<!--id 指定Bean的ID,調(diào)用SgtPeppers的默認(rèn)構(gòu)造器-->
<bean class="soundsystem.SgtPeppers" id="compactDisc"/>
</beans>
- 構(gòu)造器注入
<constructor-arg>或者Spring3.0 引入 c-命名空間 進(jìn)行注入,但是前者功能更強(qiáng)大。
<bean class="soundsystem.SgtPeppers" id="sgtPeppers">
<constructor-arg ref="sgtPeppers" name="title"/>
</bean>
<bean class="soundsystem.SgtPeppers" id="sgtPeppers"
c:title-ref="ad"
c:_0-ref="aa"
/>
<!--title 是構(gòu)造方法的參數(shù)名字,可以用index _0 表示第一個(gè),-ref 表示后面是個(gè)Bean不是字符串,
_參數(shù)名="" 表示字符常量 _index 同理-->
- 屬性注入
`<property name="asdf" ref="adsf"/> p:屬性名-ref="asdf 用法與構(gòu)造器注入完全一樣.
導(dǎo)入配置與混合配置
- @Import 在配置類上,導(dǎo)入別的配置類
@Import(Config.class),創(chuàng)建一個(gè)專門用于整合的配置類 @Import({Config1.class,Config2.class}) - @ImportResource("classpath:cd-config.xml")引入xml配置文件
- xml引入配置文件
<import resource="spring-config.xml"/>引入java配置文件,<bean class="Config.class">
Spring Profile 多環(huán)境切換配置
- 在@Profile 在配置類上或者是Bean上標(biāo)識(shí)@Profile("dev") @Profile("prod") @Profile("環(huán)境") ,XML中Beans 的profile屬性進(jìn)行指定。只有當(dāng)前設(shè)置的Profile與Bean的Profile相同時(shí),返回同一個(gè)類型的Bean時(shí),該Bean才會(huì)被實(shí)例化。沒有Profile標(biāo)識(shí)是正常實(shí)例化。
- 設(shè)置Profile
spring.profile.active spring.profile.default,當(dāng)active為設(shè)置時(shí),會(huì)讀取default的值,如果都沒有設(shè)置,只會(huì)實(shí)例化沒有profile標(biāo)識(shí)的bean。 - active和default的值設(shè)置
- DispatcherServlet的初始化參數(shù)。
<context-param>
<param-name>spring.profile.default</param-name>
<param-value>dev</param-value>
</context-param>
<servlet>
......
.. ...
<init-param>
<param-name>spring.profile.default</param-name>
<param-value>dev</param-value>
</init-param>
</servlet>
- Web應(yīng)用的上下文參數(shù)。
- JNDOI條目
- 環(huán)境變量
- jvm系統(tǒng)屬性
- 測(cè)試類上,@ActiveProfiles注解
條件化Bean
@Conditional(實(shí)現(xiàn)了Condition接口的類.class),只有當(dāng)matches返回true時(shí),才會(huì)創(chuàng)建該Conditional標(biāo)記的類。@Profile就是基于Conditional實(shí)現(xiàn)的。
自動(dòng)裝配的歧義性
- @Primary 設(shè)置該Bean為首選項(xiàng) primary=true
- 使用限定符,通過一層一層的限定,將結(jié)果限制在一個(gè)@Qualifier。
@Qualifier(id) 指定id。
@Quelifier 對(duì)該組件進(jìn)行描述。 在Autowired上設(shè)置Quelifier選擇符合條件的bean。但是java不能在同一個(gè)上重復(fù)使用。so,自定義一個(gè)注解來完成多級(jí)限定
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold {
}
通過這樣聲明多個(gè)注解,多bean就聲明了多個(gè)關(guān)鍵字,在使用是,通過這些關(guān)鍵字,進(jìn)行過濾。
Bean的作用域
默認(rèn)情況下,Bean的都是單例的,不管注入多少次都是同一個(gè)實(shí)例。
單例(Singleton) 原型(Prototype)會(huì)話(Session) 請(qǐng)求(Request)
聲明組件是@scope設(shè)置作用域。例如
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
public ShoppingCart cart(){}
這是代理模型,是因?yàn)楫?dāng)沒有會(huì)話的時(shí)候,ShoppingCart是不能注入到別的Bean中的,而別的類又已經(jīng)需要注入這個(gè)ShoppingCart對(duì)象,所以注入一個(gè)代理類,代理與Cart實(shí)現(xiàn)一樣的接口,通過代理進(jìn)行調(diào)用真正的Cart對(duì)象,同時(shí)別的類也可以正常實(shí)例化。當(dāng)需要代理的類不是接口,而是一個(gè)類的時(shí)候 需要使用的proxyMode是ScopedProxy.TARGET_CLASS.
XML中設(shè)置作用域 scope="session"
設(shè)置代理 <aop:scoped-proxy> 默認(rèn)等價(jià)與Target_Class, proxy-target-class="false"實(shí)現(xiàn)接口代理。