spring的三種主要的裝配機制

本文中使用一個接口類UserInterface以及接口的實現類UserInterfaceImpl,調用接口UserInterface的UserCall類來作示例。java

package com.springbean;

public interface UserInterface {
	void userMethod();
}
package com.springbean.impl;

import com.springbean.UserInterface;

public class UserInterfaceImpl implements UserInterface{

	public void userMethod() {
		System.out.println("UserInterfaceImpl - userMethod()");
	}

}
package com.springbean;

import java.util.List;

public class UserCall {

	private UserInterface ui;

	private String username;

	private List<String> tags;

	/**
	 * getter and setter
	 */
}

在下面,咱們即將爲UserCall注入一個UserInterface的實現類,一個字符常量以及一個集合spring

一 xml中配置

在spring的xml配置文件中配置裝配信息,配置組件bean的話只須要使用<bean>標籤便可。測試

<bean id="userInterface" class="com.springbean.impl.UserInterfaceImpl" />

假如配置的bean下面也有須要注入的參數,好比爲userCall注入userInterface的實現類和其餘參數那麼可使用兩種方式注入參數。ui

  1. 使用構造器注入。this

    能夠直接使用<constructor-arg>標籤。spa

    <util:list id="tagsList">
    	<value>cool</value>
    	<value>nice</value>
    </util:list>
    
    <bean id="userCall" class="com.springbean.UserCall">
    	<constructor-arg name="ui" ref="userInterface"/>
    	<constructor-arg name="username" value="test"/>
    	<constructor-arg name="tags" ref="tagsList"></constructor-arg>
    </bean>

    引用另外的bean時使用ref,字符串常量則使用value。code

    也可使用c-命名空間,在c-命名空間和模式聲明以後component

    <beans ...... xmlns:c="http://www.springframework.org/schema/c"
     ...... >
    </beans>
    <bean id="userCall" class="com.springbean.UserCall" c:ui-ref="userInterface" c:username="test" c:tags="tagsList" />

    使用c-命名空間能夠明顯縮短配置長度。xml

    不過使用構造器注入的時候必須在類中添加對應的構造方法纔能有效,由於注入時調用的是類的構造方法,好比userCall類中調用對象

    public UserCall(UserInterface ui, String username, List<String> tags){
    	this.ui = ui;
    	this.username = username;
    	this.tags = tags;
    }
  2. 使用屬性注入

    直接使用<property>標籤

    <bean id="userCall" class="com.springbean.UserCall">
    	<property name="ui" ref="userInterface" />
    	<property name="username" value="test" />
    	<property name="tags" value="tagsList" />
    </bean>

    使用p-命名空間

    <bean id="userCall" class="com.springbean.UserCall" p:ui-ref="userInterface" p:username="test" p:tags="tagsList" />

    屬性注入調用的是setter方法,因此類中要有相應的setter方法。

二 在Java中顯式配置

使用**@Configuration能夠將java的類文件聲明成spring的配置類,使用@Bean來聲明方法的返回對象要註冊爲spring的bean對象。並且通常的方法名即爲id名,固然也能夠爲bean指定名稱,經過其@Bean註解的name**屬性。而當bean中須要注入其餘參數或者引用時,將其做爲方法的參數便可,Spring會幫你注入這些引用,以下面的userCall方法。

package com.springbean;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.springbean.impl.UserInterfaceImpl;

@Configuration
public class SpringConfig {

	@Bean
	public String username(){
		return "test";
	}

	@Bean
	public List<String> tags(){
		List<String> tags = new ArrayList<String>();
		tags.add("cool");
		tags.add("nice");
		return tags;
	}

	@Bean
	public UserInterface userInterface(){
		return new UserInterfaceImpl();
	}

	@Bean
	public UserCall userCall(UserInterface userInterface, String username, List<String> tags){
		UserCall uc = new UserCall();
		uc.setUi(userInterface);
		uc.setUsername(username);
		uc.setTags(tags);
		return uc;
	}
}

使用java類作配置類使用時一樣和xml文件同樣須要加載,好比測試時在上下文配置信息**@ContextConfiguration**上填上配置類。

package com.springbean.demo;

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.springbean.UserCall;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=com.springbean.SpringConfig.class)
public class MainTest {

	@Autowired
	private UserCall uc;

	@Test
	public void test(){
		assertNotNull(uc);
	}

}

三 自動化裝配bean

要實現自動化裝配的關鍵之一在於能讓Spring知道有哪些組件存在,你須要手動打開Spring的組件掃描。能夠在Spring的xml文件中打開,使用

<context:component-scan base-package="com.springbean.*"/>

固然前提是引入了Spring context的命名空間,上面的示例還指定了掃描的包的位置。也能夠在java的配置類中啓用組件掃描。

package com.springbean;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class SpringConfig {

}

註解@ComponentScan指定了spring將掃描這個配置類所在的包及其子包下面的全部類。有了組件掃描後,全部被註解@Component或者@Named註解的類都將被識別爲組件類,這兩個註解均可以聲明組件的名字。

package com.springbean.impl;

import org.springframework.stereotype.Component;
import javax.inject.Named;

import com.springbean.UserInterface;

//@Component
@Named("userInterface")
public class UserInterfaceImpl implements UserInterface{

	public void userMethod() {
		System.out.println("UserInterfaceImpl - userMethod()");
	}

}

使用註解**@Autowired**能夠方便的將配置好的bean注入到想要注入的位置。

四 混合使用

不管採用何種方式去聲明一個bean,在spring中均可以任意的使用到任何地方去。自動裝配與其餘兩種方式的配合使用最簡單,只須要開啓組件掃描就好了。

以Java Config爲主,在java的配置類中使用xml配置

@Configuration
@ImportResource("classpath:springbean.xml")
public class SpringConfig {
	......
}

以xml配置爲主,在xml配置中使用java Config,使用<bean>將其導入

<bean class="com.springbean.SpringConfig" />
相關文章
相關標籤/搜索