①Bean后處理器:
Bean后處理器是一種特殊的Bean,這種特殊的Bean并不對(duì)外提供服務(wù),它甚至可以沒(méi)有id\屬性。它主要負(fù)責(zé)對(duì)容器中的其他Bean執(zhí)行后處理。
后處理器必須實(shí)現(xiàn)BeanPostProcessor接口。此接口有兩個(gè)方法:<li>Object postProcessorBeforeInitialization(Object object,String name)
<li>Object postProcessorAfterInitialization(Object object,String name)`
第一個(gè)參數(shù)是系統(tǒng)即將后處理的Bean的實(shí)例,第二個(gè)參數(shù)是該Bean實(shí)例的名稱。
例如:
public class MyBeanPostProcessor implements BeanPostProcessor{
public Object postProcessorBeforeInitialization(Object object,String name) throws Beanexception{
System.out.println("后處理器在初始化之前對(duì)"+"name"+"進(jìn)行增強(qiáng)處理");
return object;
}
public Object postProcessorAfterInitialization(Object object,String name) throws Beanexception{
System.out.println("后處理器在初始化之后對(duì)"+"name"+"進(jìn)行增強(qiáng)處理");
if(object intanceof Chinese ){
Chinese c = (Chinese)bean;
bean.setName="張三";
}
return object;
}
}
public class Chinese implements Person{
private Axe axe;
private String name;
public void setName(String name){
System.out.println("Spring執(zhí)行注入.......");
this.name=name;
}
//set/get....
public void init(){
System.out.println("初始化工作init");
}
...............................
}
<bean id="steelAxe" class="..."/>
<bean id="chinese" class="Chinese">
<property name="axe" ref="steelAxe"/>
<prperty name="name" value="李四"/>
</bean>
<!--配置后處理器-->
<bean id="beanPostProcessor" class="MyBeanPostProcessor"/>
public static void mian(String args[]){
ClassPathResource rs = new ClasspathReource(bean.xml);
XmlBeanFactory factory = new XmlBeanfactory(rs);
MyBeanPostProcessor processor = (MyBeanPostProcessor)factory.getBean("beanPostProcessor")
//注冊(cè)BeanPostProcessor
factory.addPostProcessor(processor )
Person p = (Person)factory.getBean("chinese");
p.useAxe();
}
程序輸出name屬性時(shí),不會(huì)輸出李四,而是張三,雖然注入的值是李四,但是Bean后處理器發(fā)生作用。
輸出:
Spring執(zhí)行注入依賴關(guān)系......
后處理器在初始化之前對(duì)chinese進(jìn)行增強(qiáng)處理
初始化工作init
后處理器在初始化之后對(duì)chinese進(jìn)行增強(qiáng)處理
張三
如果使用BeanFactory作為Spring的容器。則必須手動(dòng)注冊(cè)Bean后處理器,容器中一旦注冊(cè)了Bean后處理器,Bean后處理器就會(huì)自動(dòng)啟動(dòng),在容器中每個(gè)Bean創(chuàng)建時(shí)自動(dòng)工作。
實(shí)現(xiàn)BeanPostProcessor接口的Bean后處理器可以對(duì)Bean進(jìn)行任何操作,包括完全忽略這個(gè)回調(diào),BeanPostProcessor通常用來(lái)檢查標(biāo)記接口,或者做將Bean包裝成一個(gè)Proxy的事情。
如果不采用BeanFactory作為Spring的容器,采用ApplicationContext作為容器,則無(wú)需手動(dòng)注冊(cè)Bean后處理器,ApplicationContext可自動(dòng)檢測(cè)到容器中的Bean后處理器,自動(dòng)注冊(cè)。Bean后處理器會(huì)在創(chuàng)建Bean時(shí)自動(dòng)啟動(dòng)。對(duì)于后處理器而言,ApplicationContext作為Spring容器更為方便。
②容器后處理器:
除了上面的提供的Bean后處理器外,Spring還提供了一種容器后處理器,,Bean后處理器負(fù)責(zé)容器中所有Bean實(shí)例的,而容器后處理器負(fù)責(zé)處理容器本身。
容器后處理器必須要實(shí)現(xiàn)BeanFactoryPostProcessor接口。
類似于Bean后處理器,采用ApplicationContext作為容器,則無(wú)需手動(dòng)注冊(cè)容器后處理器.如果使用BeanFactory作為Spring的容器。則必須手動(dòng)注冊(cè)容器后處理器.
2.Spring的“零配置”支持
①搜索Bean類
Spring提供如下幾個(gè)Annotation來(lái)標(biāo)注Spring Bean:
<li>Component:標(biāo)注一個(gè)普通的Spring Bean;
<li>Controller:標(biāo)注一個(gè)控制器組件類;
<li>Service:標(biāo)注一個(gè)業(yè)務(wù)邏輯組件類;
<li>Repository:標(biāo)注一個(gè)Dao組件;
<context:component-scan base-package=""/>
在默認(rèn)的情況下,自動(dòng)搜索所有以@Component、@Controller、@Service、@Repository注釋的java類,當(dāng)作Spring Bean處理。
還可以通過(guò)
<context:component-scan base-package=""/>
子元素
<include-filter>/<exclude-filter>
②指定Bean的作用域:
如:
@Scope("prototype")
@Component("axe")
public class SteelAxe implements Axe{
}
③使用@Resource配置依賴:
@Resource有一個(gè)name屬性,在默認(rèn)的情況下,Spring將這個(gè)值 解釋為需要被注入的Bean的實(shí)例的名字,換句話說(shuō),使用@Resource與<property../>元素的ref屬性具有相同的效果。
當(dāng)使用@Resource修飾setter方法,如果省略name屬性,則name屬性默認(rèn)是從該setter方法去掉set子串,首字母小寫的到的子串。
當(dāng)使用@Resource修飾Field時(shí),如果mane,則默認(rèn)與Field的相同。
④自動(dòng)裝配和精確裝配:
Spring提供@Autowired來(lái)指定自動(dòng)裝配,使用@Autowired可以標(biāo)志setter方法、普通方法、和構(gòu)造器。如:
@Component
public class Chinese implements Person{
@Autowired
private Aex axe;
@Autowired
public Chinese(Axe axe){
this.axe = axe
}
@Autowired
private Axe [] axes;
}
當(dāng)@Autowired標(biāo)注Field時(shí)Spring會(huì)把容器中的與該Field類型匹配的Bean注入該屬性.
如果Spring容器中有多個(gè)同類型的Bean與Field類型匹配,則會(huì)出現(xiàn)異常。
當(dāng)@Autowired標(biāo)注數(shù)組類時(shí),在這種情況,Spring會(huì)自動(dòng)搜索Spring容器中所有與數(shù)組類型相匹配的類型的Bean,并把這些Bean當(dāng)作數(shù)組的元素來(lái)創(chuàng)建數(shù)組。
當(dāng)@Autowired標(biāo)注集合時(shí),和標(biāo)注數(shù)組類似,當(dāng)時(shí)必須使用泛型.
⑤使用@Qualifier精確裝配
正如上面的@Autowired總是采用byType的自動(dòng)裝配策略。在這種情況下,符合自動(dòng)和裝配的類型的Bean常常有多個(gè)這個(gè)時(shí)候就會(huì)引發(fā)異常了。
為了實(shí)現(xiàn)精確的配置,Spring提供@Qualifier,可以根據(jù)Bean標(biāo)識(shí)來(lái)指定自動(dòng)裝配.
--- @Qualifier可以標(biāo)注Field,如:
@Component
public class Chinese implements Person{
@Autowired
@Qualifier("steelAxe")
private Aex axe;
}
--- @Qualifier還可以標(biāo)注方法的形參,如:
@Component
public class Chinese implements Person{
@Autowired
private Aex axe;
public void setAxe(@Qualifier("steelAxe") Axe axe )
this.axe=axe;
}
}