Spring容器負責建立應用程序中的bean,並經過DI來協調對象之間的關係。Spring提供了三種主要的裝配機制:git
推薦使用Java配置類結合隱式的自動bean掃描機制。github
XML配置是Spring剛出現時的主要配置方式。這種方式須要手動編寫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時,能夠直接利用應用上下文進行加載XML,spring-mvc
//把beans.xml的類加載到容器
ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
//從容器中獲取bean
Person person = (Person) app.getBean("person");
System.out.println(person);
複製代碼
在進行顯式配置時,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
- 修改返回bean的方法名,上面的例子中,bean id默認爲person。能夠將其修改成person1(),則id變爲person01
- 直接在@Bean中指定,上面的例子,bean id爲myPerson
能夠直接使用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);
}
}
}
複製代碼
除了上面介紹的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來替代它,同時這些註解會具有有更多的功能,並且功能各異。
總結以下:
定義組件的方式很簡單,直接在定義好的類上面使用註解便可。此外,能夠在定義組件的同時,指定組件的名稱,
@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)
複製代碼
其中須要設置以下的參數:
掃描的Type能夠爲以下幾類:
注意到可使用自定義規則,這個狀況下須要本身編寫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精品面試課程。