Spring注入Bean的幾種方式

經過註解注入Bean

背景

咱們談到Spring的時候必定會提到IOC容器、DI依賴注入,Spring經過將一個個類標註爲Bean的方法注入到IOC容器中,達到了控制反轉的效果。那麼咱們剛開始接觸Bean的時候,必定是使用xml文件,一個一個的注入,就例以下面這樣。java

<bean id="bean" class="beandemo.Bean" />
複製代碼

咱們的項目通常很大的話,就須要成千上百個Bean去使用,這樣寫起來就很繁瑣。那麼Spring就幫咱們實現了一種經過註解來實現注入的方法。只須要在你須要注入的類前面加上相應的註解,Spring就會幫助咱們掃描到他們去實現注入。ide

xml掃描包的方式this

<context:component-scan base-package="com.company.beandemo"/>
複製代碼

經過註解注入的通常形式

通常狀況下,注入Bean有一個最直白,最易懂的方式去實現注入,下面廢話先很少說,先貼代碼。spa


  • Bean類
public class MyBean{
	}
複製代碼
  • Configuration類
//建立一個class配置文件
	@Configuration
	public class MyConfiguration{
		//將一個Bean交由Spring進行管理
        @Bean
        public MyBean myBean(){
            return new MyBean();
        }
	}
複製代碼
  • Test類

與xml有一點不一樣,這裏在Test中,實例化的再也不是ClassPathXmlApplicationContext,而是獲取的AnnotationConfigApplicationContext實例。翻譯

ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
	MyBean myBean = cotext.getBean("myBean",MyBean.class);
	System.out.println("myBean = " + myBean);
複製代碼

上面的代碼中MyBean也就是咱們須要Spring去管理的一個Bean,他只是一個簡單的類。而MyConfiguration中,咱們首先用@Configuration註解去標記了該類,這樣標明該類是一個Spring的一個配置類,在加載配置的時候會去加載他。code

在MyConfiguration中咱們能夠看到有一個方法返回的是一個MyBean的實例,而且該方法上標註着@Bean的註解,標明這是一個注入Bean的方法,會將下面的返回的Bean注入IOC。component

經過構造方法注入Bean

咱們在生成一個Bean實例的時候,可使用Bean的構造方法將Bean實現注入。直接看代碼xml


  • Bean類
@Component
	public class MyBeanConstructor {

    	private AnotherBean anotherBeanConstructor;

    	@Autowired
    	public MyBeanConstructor(AnotherBean anotherBeanConstructor){
     	   this.anotherBeanConstructor = anotherBeanConstructor;
    	}

    	@Override
    	public String toString() {
        	return "MyBean{" +
            	"anotherBeanConstructor=" + anotherBeanConstructor +
            	'}';
    	}
	}
複製代碼
  • AnotherBean類
@Component(value="Bean的id,默認爲類名小駝峯")
	public class AnotherBean {
	}
複製代碼
  • Configuration類
@Configuration
	@ComponentScan("com.company.annotationbean")
	public class MyConfiguration{
	}
複製代碼

這裏咱們能夠發現,和通常方式注入的代碼不同了,咱們來看看新的註解都是什麼意思:對象

  • @AutoWired

簡單粗暴,直接翻譯過來的意思就是自動裝配:wrench:,還不理解爲何叫自動裝配:wrench:?看了下一個註解的解釋你就知道了。如果在這裏注入的時候指定一個Bean的id就要使用@Qualifier註解get

  • @Component(默認單例模式)

什麼??這翻譯過來是零件,怎麼感受像是修汽車??是的,Spring管理Bean的方法就是修汽車的方式。咱們在須要將一個類變成一個Bean被Spring能夠注入的時候加上註解零件@Conmonent,那麼咱們就能夠在加載Bean的時候把他像零件同樣裝配:wrench:到這個IOC汽車上了

在這裏咱們還有幾個其餘的註解也能夠實現這個功能,也就是細化的@Component:

    • @Controller 標註在Controller層
    • @Service 標註在Service層
    • @Repository 標註在dao層
  • @ComponentScan("")

仍是翻譯,零件掃描,咱們去看看括號裏的「零件倉庫」裏面,哪些「零件」(類)須要被裝載,Spring就會去掃描這個包,將裏面全部標註了@Component的類進行注入。

這裏的經過構造方法進行注入就很好理解了,咱們在裝配MyBean這個零件的時候,忽然發現他必須在AnotherBean的基礎上才能安裝到IOC裏面,那麼咱們就在每次裝配MyBean的時候自動裝配:wrench:一個AnotherBean進去。舉個:chestnut:吧:

仍是以汽車爲例,咱們在踩油門出發以前,是否是必須發車??這裏的AutoWired的內容就像發車,你不發車,這個油門你踩斷都沒有用,他都不會走。

經過set方法注入Bean

咱們能夠在一個屬性的set方法中去將Bean實現注入,看代碼吧


  • MyBean類
@Component
	public class MyBeanSet {

    	private AnotherBean anotherBeanSet;

    	@Autowired
    	public void setAnotherBeanSet(AnotherBean anotherBeanSet) {
        	this.anotherBeanSet = anotherBeanSet;
    	}

    	@Override
    	public String toString() {
        	return "MyBeanSet{" +
            	"anotherBeanSet=" + anotherBeanSet +
            	'}';
    	}
	}
複製代碼
  • Configuration類 和 Test類

同上一個,就不貼了


這裏咱們發如今setter方法上咱們有一個@AutoWired,與上面不一樣的是,咱們不會在實例化該類時就自動裝配:wrench:這個對象,而是在顯式調用setter的時候去裝配。

經過屬性去注入Bean

咱們前面兩種注入的方式諸如時間不一樣,而且代碼較多,如果經過屬性,即就是

@Component
	public class MyBeanProperty {

    	@Autowired
    	private AnotherBean anotherBeanProperty;

    	@Override
    	public String toString() {
        	return "MyBeanProperty{" +
            	"anotherBeanProperty=" + anotherBeanProperty +
            	'}';
    	}
	}
複製代碼

這裏咱們能夠看到咱們這個類中須要使用AnotherBean這個實例對象,咱們能夠經過@AutoWired去自動裝配它。

對於有些小夥伴問私有屬性,Spring怎麼去加載它到IOC的?推薦去看看反射

經過List注入Bean

  • MyBeanList類
@Component
	public class MyBeanList {

    	private List<String> stringList;

    	@Autowired
    	public void setStringList(List<String> stringList) {
        	this.stringList = stringList;
    	}

    	public List<String> getStringList() {
        	return stringList;
    	}
	}
複製代碼
  • MyConfiguration類
@Configuration
	@ComponentScan("annoBean.annotationbean")
	public class MyConfiguration {

	    @Bean
	    public List<String> stringList(){
	       List<String> stringList = new ArrayList<String>();
 	       stringList.add("List-1");
 	       stringList.add("List-2");
 	       return stringList;
	    }
	}
複製代碼

這裏咱們將MyBeanList進行了注入,對List中的元素會逐一注入。下面介紹另外一種方式注入List

  • MyConfiguration類
@Bean
    //經過該註解設定Bean注入的優先級,不必定連續數字
    @Order(34)
    public String string1(){
        return "String-1";
    }

    @Bean
    @Order(14)
    public String string2(){
        return "String-2";
    }
複製代碼

注入與List中泛型同樣的類型,會自動去匹配類型,及時這裏沒有任何List的感受,只是String的類型,但他會去經過List的Bean的方式去注入。

第二種方式的優先級高於第一種,當兩個都存在的時候,若要強制去使用第一種方式,則要去指定Bean的id便可

經過Map去注入Bean

@Component
	public class MyBeanMap {

    	private Map<String,Integer> integerMap;

    	public Map<String, Integer> getIntegerMap() {
    	    return integerMap;
    	}

    	@Autowired
    	public void setIntegerMap(Map<String, Integer> integerMap) {
    	    this.integerMap = integerMap;
    	}
	}
複製代碼
@Bean
    public Map<String,Integer> integerMap(){
        Map<String,Integer> integerMap = new HashMap<String, Integer>();
        integerMap.put("map-1",1);
        integerMap.put("map-2",2);
        return integerMap;
    }

    @Bean
    public Integer integer1(){
        return 1;
    }

    @Bean
    public Integer integer2(){
        return 2;
    }
複製代碼

一樣這裏也具備兩種方式去注入Map類型Bean,且第二種的優先值高於第一種

以上就是Bean經過註解注入的幾種方式,你們能夠對比着xml注入的方式去看。

相關文章
相關標籤/搜索