一、Spring的容器:
1.什么是控制反轉:傳統的方法,當某個(gè)java對象A需要調用對象B時(shí),是由調用者(對象A)通過(guò)new關(guān)鍵字來(lái)創(chuàng )建對象B的,而在Spring中,則是由spring完成創(chuàng )建的,所以“控制反轉”了。
2.容器:
Spring容器是Spring的核心。
實(shí)例化一個(gè)spring容器,容器會(huì )自動(dòng)預初始化所有Bean實(shí)例。
ApplicationContext ac = new ClassPathXmlApplicationContext('bean.xml'); //實(shí)例化一個(gè)Spring容器,Boss boss = (Boss) ac.getBean('boss'); //取得對象boss
二、裝配(注入):
1.設置注入:屬性必須寫(xiě)setter方法。格式為:
<bean id=' ' class=' '>
<property name=' ' value=' ' />
<property name=' ' value=' ' />
</bean>
<bean id='boss' class='wang.spring.Boss'> <property name='car' ref='car'/> <property name='office' ref='office' /> </bean> <bean id='office' class='wang.spring.Office'> <property name='officeNo' value='002'/> </bean> <bean id='car' class='wang.spring.Car' scope='singleton'> <property name='brand' value=' 紅旗 CA72'/> <property name='price' value='2000'/> </bean>
2.構造注入:必須寫(xiě)有參的構造函數。
<bean id='car' class='wang.spring.Car '>
<constructor-arg index=' 0' type=“int” value=' 001” />
<constructor-arg index=' 1' type=“String” value=' baoma” />
</bean>
利用上面代碼,可以新建一個(gè)實(shí)例car,并給它的屬性賦值。
3.依賴(lài)注入:當引用了其他類(lèi)的對象時(shí)。
<property name=' ' ref=' '>
或者
<constructor-arg ref=' '>
<beans> <bean id=”bean1” class=”……”> <property name=”屬性1” value=”……”/> </bean> <bean id=”bean2” class=”……”> <property name=”bean1” ref=”bean1”/> </bean> </beans>
4.集合的注入:
Set集合注入:
<bean id=”……” class=”……”> <set> <value>value1</value> <value>value2</value> …… </set> </bean>
Lsit集合注入:
<bean id=”……” class=”……”> <list> <value>value1</value> <value>value2</value> …… </list> </bean>
Map集合注入:
<bean id=”……” class=”……”> <map> <entry key=”key1” value=”value1”> <entry key=”key2” value=”value2”> …… </map> </bean>
Properties注入:
<bean id=”……” class=”……”><props> <prop key=”key1”>value1</prop> <prop key=”key2”>value2</prop> …… </props></bean>
5.自動(dòng)注入:
通過(guò)bean里的屬性autowire可以自動(dòng)注入實(shí)例。
no:不使用自動(dòng)裝配。這是默認配置。
byName:根據屬性自動(dòng)裝配,BeanFactory會(huì )查找容器中所有的Bean,找出id屬性與屬性名同名的Bean來(lái)完成注入。如果沒(méi)有找到匹配的Bean,Spring則不會(huì )進(jìn)行任何注入。
byType:根據屬性類(lèi)型自動(dòng)裝配,BeanFactroy會(huì )查找容器中所有的 Bean,如果一個(gè)正好與依賴(lài)屬性類(lèi)型相同的Bean,就會(huì )自動(dòng)注入這個(gè)屬性。
如果有多個(gè)這樣的Bean則會(huì )拋出異常。如果沒(méi)有這樣 的Bean則什么也不會(huì )發(fā)生,屬性不會(huì )被設置。
<bean class='dao.OrderDaoImpl' autowire='byName'></bean> <bean class='dao.ItemDaoImpl'></bean> <bean id='storeService' class='service.StoreServiceImpl'></bean> </beans>
三、通過(guò)注解自動(dòng)裝配:
注解可以分為兩大類(lèi)。JSR-250規范注解方式 和 Spring自帶的注解方式。
通過(guò)注解的方式裝配時(shí),必須在配置文件中添加一個(gè)bean,它其實(shí)是一個(gè)注解處理器,用于解析注解。
JSR-250規范注解方式的處理器:
<bean class='org.springframework.context.annotation.CommonAnnotationBeanPostProcessor'/>
Spring自帶的注解方式的處理器:
<bean class='org.sprinframework.beans.factory.annotation. AutowiredAnnotationBeanPostProcessor'/>
當然,我們有更方便的方法,兩種注解方式都可以用下面的方式隱式得注冊注解處理器:
<context:annotation-config>
1.JSR-250規范注解方式:
@Resource
默認是按照名稱(chēng)匹配(byName),但它有兩個(gè)屬性,name和type。分別可以指定自動(dòng)匹配的類(lèi)型。
標注在成員變量,setter方法,構造函數上都可以。
public class Boss { // 自動(dòng)注入類(lèi)型為 Car 的 Bean @Resource private Car car; // 自動(dòng)注入 bean 名稱(chēng)為 office 的 Bean @Resource(name = 'office') private Office office;}
2.Spring自帶的注解方式:
@Autowired
按照類(lèi)型匹配(byType)
標注在成員變量,setter方法,構造函數上都可以。
因為這種注解是按照類(lèi)型注入的,所以要有多個(gè)同類(lèi)型的對象,則會(huì )出現異常。此時(shí)我們可以用@Qualifier指定對象的名稱(chēng),兩者結合使用,便可以確定一個(gè)對象。
public class Boss {
@Autowired @Qualifier('office') private Office office; //當在成員變量上標注時(shí),不需要寫(xiě)setter方法…} @Qualifier的標注對象是成員變量、方法入參、構造函數入參。正是由于注釋對象的不同,所以 Spring 不將 @Autowired 和@Qualifier 統一成一個(gè)注釋類(lèi)。(@Qualifier只能結合@Autowired使用,不能單獨使用)
四、實(shí)現零配置:
我們可以通過(guò)上面兩種注解方式,在bean中實(shí)現自動(dòng)注入。但是bean還得在xml文件中通過(guò)<bean>進(jìn)行定義。那我們能不能也通過(guò)注解方式定義bean,實(shí)現零配置呢。答案是肯定的。
Spring提供如下幾個(gè)Annotation來(lái)標注Spring Bean:
@Component標注一個(gè)普通的Spring Bean;
@Controller:標注一個(gè)控制器組件類(lèi);
@Service:標注一個(gè)業(yè)務(wù)邏輯組件類(lèi);
@Repository:標注一個(gè)Dao組件;
目前Component可在各層通用。
@Componentpublic class Boss { @Autowired private Car car; @Autowired private Office office; …}
這時(shí),bean.xml文件中就不必用<bean>來(lái)定義bean了。只需添加一行<context:component-scan base-package='com.baobaotao'/>用來(lái)指定這些類(lèi)所在的包。
<context:component-scan base-package='com.baobaotao'/>