Spring MVC系列-(2) Bean的裝配

Spring.png

2. Bean的裝配

Spring容器負責建立應用程序中的bean,並經過DI來協調對象之間的關係。Spring提供了三種主要的裝配機制:git

  • XML顯式配置;
  • Java配置類進行顯式配置;
  • 隱式的bean發現機制和自動裝配。

推薦使用Java配置類結合隱式的自動bean掃描機制。github

2.1 經過XML裝配Bean

XML配置是Spring剛出現時的主要配置方式。這種方式須要手動編寫XML,並在其中配置好Bean的定義。面試

建立XML並定義Bean

下面是Person類的定義,spring

public class Person {
	private String name;
	private Integer age;
	
	public Person(){
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Person(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Integer getAge() {
		return age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}
複製代碼

能夠在XML進行以下的配置,設置了bean id以及相應的屬性值。後端

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="person" class="com.enjoy.cap1.Person">
		<property name="name" value="vincent"></property>
		<property name="age" value="19"></property>
	</bean>
</beans>
複製代碼

獲取Bean

在使用Bean時,能夠直接利用應用上下文進行加載XML,spring-mvc

//把beans.xml的類加載到容器
ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");

//從容器中獲取bean
Person person = (Person) app.getBean("person");
		
System.out.println(person);
複製代碼

2.2 經過Java配置類裝配Bean

在進行顯式配置時,Java配置類是更好的方案,由於它更爲強大,類型安全而且對重構友好。安全

建立Java配置類

建立Java配置類的關鍵在於爲其添加@Configuration註解,代表這個類是一個配置類。在這種方式下,不須要XML配置文件。bash

下面的例子中,往容器中註冊了一個Person的Bean實例。mvc

//配置類====配置文件
@Configuration
public class MainConfig {
	//給容器中註冊一個bean, 類型爲返回值的類型, 
	@Bean("myPerson")
	public Person person(){
		return new Person("vincent",20);
	}
}
複製代碼

修改bean id有兩種方法:app

  1. 修改返回bean的方法名,上面的例子中,bean id默認爲person。能夠將其修改成person1(),則id變爲person01
  2. 直接在@Bean中指定,上面的例子,bean id爲myPerson

獲取Bean

能夠直接使用AnnotationConfigApplicationContext加載配置類,並獲取Bean。

public class MainTest2 { 
	public static void main(String args[]){
		
		// 利用configure類配置bean實例
		ApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
		
		//從容器中獲取bean
		Person person = (Person) app.getBean("myPerson");
		System.out.println(person);
		
		// 獲取全部的bean name
		String [] beanNameList = app.getBeanDefinitionNames();
		for (String name : beanNameList) {
			System.out.println(name);
		}
	}
}

複製代碼

2.3 自動化裝配Bean

除了上面介紹的XML和Java配置類來進行Bean的裝配,Spring還支持自動化裝配。

聲明配置類

一樣的,在自動化裝配Bean時,也須要聲明Java配置類,

@Configuration
@ComponentScan(value = "com.enjoy.cap2", includeFilters = {
		@Filter(type=FilterType.CUSTOM, classes = {JamesTypeFilter.class})
}, useDefaultFilters = false)

public class Cap2MainConfig {
	//給容器中註冊一個bean, 類型爲返回值的類型, 
	@Bean
	public Person person01(){
		return new Person("james",20);
	}
}
複製代碼

所不一樣的是,加入了ComponentScan註解,該註解會啓動組件掃描,默認狀況下會掃描與配置類相同的包,若是查找到了帶有Component註解的類,會自動建立對應的bean並放置到容器中。

定義被掃描的組件

在Spring 2.5以後,引入了3個註解@Repository@Service@Controller。這些組件均可以被自動掃描而且加載到容器中。

相比較而言,@Component是一個通用的Spring容器管理的單例bean組件。而@Repository, @Service, @Controller就是針對不一樣的使用場景所採起的特定功能化的註解組件。所以,當你的一個類被@Component所註解,那麼就意味着一樣能夠用@Repository, @Service, @Controller來替代它,同時這些註解會具有有更多的功能,並且功能各異。

總結以下:

  • @Component:最普通的組件,能夠被注入到spring容器進行管理
  • @Repository:做用於持久層
  • @Service:做用於業務邏輯層
  • @Controller:做用於表現層(spring-mvc的註解)

定義組件的方式很簡單,直接在定義好的類上面使用註解便可。此外,能夠在定義組件的同時,指定組件的名稱,

@Controller("testController")
public class OrderController {}
複製代碼

定製包掃描的過濾規則

在下面的例子中,加入@Filter來定製掃描規則。

@ComponentScan(value="com.enjoy.cap2",
includeFilters={		            @Filter(type=FilterType.ANNOTATION,classes={Controller.class}),	@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class})
},
useDefaultFilters=false) 
複製代碼

其中須要設置以下的參數:

  • value:指定要掃描的包
  • excludeFilters = Filter[]: 指定掃描的時候按照什麼規則排除那些組件
  • includeFilters = Filter[]: 指定掃描的時候只須要包含哪些組件
  • useDefaultFilters = false: 默認是true,掃描全部組件,要改爲false

掃描的Type能夠爲以下幾類:

  • FilterType.ANNOTATION:按照註解
  • FilterType.ASSIGNABLE_TYPE:按照給定的類型;好比按BookService類型
  • FilterType.ASPECTJ:使用ASPECTJ表達式
  • FilterType.REGEX:使用正則指定
  • FilterType.CUSTOM:使用自定義規則,自已寫類,實現TypeFilter接口

注意到可使用自定義規則,這個狀況下須要本身編寫FilterType類,而且重寫match函數,在這個函數中定義匹配規則。

public class JamesTypeFilter implements TypeFilter{

	/*
	 * MetadataReader:讀取到當前正在掃描類的信息
	 * MetadataReaderFactory:能夠獲取到其餘任何類信息
	 */
	@Override
	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {
		//獲取當前類註解的信息
		AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
		//獲取當前正在掃描的類信息
		ClassMetadata classMetadata = metadataReader.getClassMetadata();
		//獲取當前類資源(類的路徑)
		Resource resource = metadataReader.getResource();
		
		String className = classMetadata.getClassName();
		System.out.println("----->"+className);
		if(className.contains("Service")){//當類包含er字符, 則匹配成功,返回true
			return true;
		}
		return false;
	}
}
複製代碼

使用時,指定type爲CUSTOM,而且設置class類型爲自定義的Filter類。

@ComponentScan(value="com.enjoy.cap2",includeFilters={
		@Filter(type=FilterType.CUSTOM,classes=         {JamesTypeFilters.class}
)},
useDefaultFilters=false) 
public class Cap2MainConfig2 {}
複製代碼

本文由『後端精進之路』原創,首發於博客 teckee.github.io/ , 轉載請註明出處

搜索『後端精進之路』關注公衆號,馬上獲取最新文章和價值2000元的BATJ精品面試課程

後端精進之路.png
相關文章
相關標籤/搜索