關於spring的幾種注入方式
理解類之間的關聯關系
一,set注入
在這之前我們得spring的jar包,可以去官網下,添加到WebContent下 WEB-INF 下 lib里

這種方式就得首先實現set方法,現在以英雄(Hero接口)和武器(weapon)為例講解
第一步,首先我們創建兩個接口
英雄接口
package com.inter;
public interface Hero {
void fight();
}
武器接口
package com.inter;
public interface Weapon {
void attack();
}
第二步,然后我們建立兩個實現類呂布(Lvbu)實現Hero接口,方天畫戟(FangTianHuaJi)實現Weapon
package com.test;
import com.inter.Hero;
import com.inter.Weapon;
public class Lvbu implements Hero{
Weapon weapon;
public Weapon getWeapon() {
return weapon;
}
//shi
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
@Override
public void fight() {
System.out.println("呂布拿起武器");
weapon.attack();
}
}
package com.test;
import com.inter.Weapon;
public class FangTianHuaJi implements Weapon {
@Override
public void attack() {
// TODO Auto-generated method stub
System.out.println("方天畫戟卡卡砍");
}
}
再來一個武器青龍偃月刀
package com.test;
import com.inter.Weapon;
public class Qing implements Weapon{
@Override
public void attack() {
// TODO Auto-generated method stub
System.out.println("青龍偃月殺殺");
}
}
第三步,我們得創建一個配置文件spring.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="lvbu" class="com.test.Lvbu">
<!-- set注入 -->
<property name="weapn" ref="fang"></property>
</bean>
<bean id="fang" class="com.test.FangTianHuaJi">
</bean>
</beans>
第四步,建立一個測試main
package com.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.inter.Hero;
import com.inter.Performer;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
//獲取配置文件
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
//得到英雄類
Hero per=(Hero)context.getBean("lvbu");
per.fight();
}
}
結果

二,自動裝配autowire
byName,當我們的呂布有兩個屬性的時候,也就是說他有兩把武器的時候,我們還是這樣寫,就會報錯。將FangTianHuaJi類的id去了一個和lvbu類的屬性weapon一樣的名字,並且在lvbu bean中添加了autowire="byName"用於指明裝配類型是byName自動裝配。這個時候lvbu bean就是在上下文中找名為weapon的bean裝配到他自己的weapon屬性中。

byType,這里已經不用關注FangTianHuaJi類對應的bean的id是什么了,因為已經定義lvbu bean的autowire屬性為"byType"。這個時候lvbu bean會在上下文中尋找和weapon具有相同類型的類對應的bean。這里兩把刀是相同的屬性,所以還這樣寫就會報錯
一種方法是將其中一個bean的primary屬性設為false,比如:將青龍偃月Qing bean的primary屬性設為true,那么呂布的武器就變成青龍偃月刀了

三,使用注解 @Autowired 自動裝配
通過基於注解的方式,可以不用在xml文件中為guanyu bean添加autowire屬性了,但是注意加啟動注解標簽
spring.xml
<!-- 當我們使用注解時需要啟動注解 -->
<context:annotation-config />
<bean id="lvbu" class="com.test.Lvbu" ></bean>
<bean id="weapon" class="com.test.FangTianHuaJi" ></bean>
還有要在呂布的武器屬性上加@Autowired,表明注解自動注入
package com.test;
import org.springframework.beans.factory.annotation.Autowired;
import com.inter.Hero;
import com.inter.Weapon;
public class Lvbu implements Hero{
//需要在屬性頭上添加注解
@Autowired
Weapon weapon;
public Weapon getWeapon() {
return weapon;
}
//set注入,時必須寫
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
@Override
public void fight() {
System.out.println("呂布拿起武器");
weapon.attack();
}
}
注意這里我們和上面一樣,我們有兩個同類型的武器時,我們還是要做區分,添加@Qualifier注解
xml添加
<!-- 當我們使用注解時需要啟動注解 -->
<context:annotation-config />
<bean id="lvbu" class="com.test.Lvbu" ></bean>
<bean id="fang" class="com.test.FangTianHuaJi" >
<qualifier value="weaponoflvbu"></qualifier>
</bean>
<bean id="qing" class="com.test.Qing"></bean>
這里的呂布武器也要添加@Qualifier注解
package com.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.inter.Hero;
import com.inter.Weapon;
public class Lvbu implements Hero{
//需要在屬性頭上添加注解
@Autowired
//要和配置的對應
@Qualifier("weaponoflvbu")
Weapon weapon;
public Weapon getWeapon() {
return weapon;
}
//set注入,時必須寫
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
@Override
public void fight() {
System.out.println("呂布拿起武器");
weapon.attack();
}
}
也可以更簡單的寫,直接在@Qalifier();里加id
<!-- 當我們使用注解時需要啟動注解 -->
<context:annotation-config />
<bean id="lvbu" class="com.test.Lvbu" ></bean>
<bean id="fang" class="com.test.FangTianHuaJi" ></bean>
<bean id="qing" class="com.test.Qing"></bean>

四,spring的自動檢測
context:component-scan元素會掃描指定的包以及所有子包,並查找出能夠自動注冊為Spring Bean的類。base-package屬性標示了context:component-scan元素所掃描的包。
為自動檢測標注Bean
默認情況下,context:component-scan查找使用構造型(stereotype)注解所標注的類,這些特殊的注解如下:
類型 說明
@component 通用的構造型注解,標示該類為Spring 組件。
@Controller 標識將該類定義為Spring MVC controller。
@Repository 標識將該類定義為數據倉庫(例如:Dao層)。
@Service 標識將該類定義為服務(例如:Service層)。
這里我們就是普通的寫,所以就使用@component ,其實這幾個注解都可以用,只是我們感覺其他的不合適
xml配置
<context:component-scan base-package="com.test"></context:component-scan>
<bean id="lvbu" class="com.test.Lvbu" ></bean>
<!-- 用注解對應了就不用寫bean了 -->
package com.test;
import org.springframework.stereotype.Component;
import com.inter.Weapon;
//屬於呂布的武器
@Component("weaponOflvbu")
public class FangTianHuaJi implements Weapon {
@Override
public void attack() {
// TODO Auto-generated method stub
System.out.println("方天畫戟卡卡砍");
}
}
package com.test;
import org.springframework.stereotype.Component;
import com.inter.Weapon;
//屬於關羽 的武器
@Component("weaponOfguanyu")
public class Qing implements Weapon{
@Override
public void attack() {
// TODO Auto-generated method stub
System.out.println("青龍偃月殺殺");
}
}
package com.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.inter.Hero;
import com.inter.Weapon;
public class Lvbu implements Hero{
//需要在屬性頭上添加注解
@Autowired
//要和配置的對應,如果一個接口只對應一個實現類的話就都不用寫qualifier
@Qualifier("weaponOflvbu")
Weapon weapon;
public Weapon getWeapon() {
return weapon;
}
//set注入,時必須寫
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
@Override
public void fight() {
System.out.println("呂布拿起武器");
weapon.attack();
}
}
