譯者:kefate 原文:https://github.com/google/guice/wiki/Overview 大家好,我是kefate。今天開始我將會把Google Guice的官方文檔陸續翻譯一遍,水平有限,若有翻譯不妥之處,還望各位不吝指出。OK,話不多說,下麵開始今天的正文~ Guic ...
1.@Component註解與其衍生註解
(1) 在Spring中,@Component註解用於說明某個類是一個bean,之後Spring在類路徑掃描過程中會將該bean添加至容器中;@Component註解還有很多衍生註解,如@Repository, @Service和@Controller,它們分別用於三層架構中的持久層,業務層和控制層,因此,對於一個業務層的普通Service類,一般情況下用@Component或@Service都是可行的,但更推薦用@Service註解,因為該註解不僅能清晰的指明被標註的類是一個業務類,此外,這些註解還是Spring AOP的理想切入目標,能方便的對某一層進行切入(例如:切入控制層,進行許可權校驗)
(2) Spring提供的許多註解都可以用作元註解,如Spring的@RestController註解,它就是將@Controller和@ResponseBody註解組合出來的一個新註解,使用該註解,在我們期望類中所有方法都返回json格式數據時,就不用在每一個方法上都標註@ResponseBody註解了,因此,Spring推薦我們根據業務需要,結合元註解來實現自定義註解
2.自動掃描並註冊bean
(1) 上文我們提到了@Component註解等,那麼,Spring該如何掃描到這些註解並將它們註入進容器中呢? 這就需要類路徑掃描註解@ComponentScan了,我們需要把它添加到有@Configuration註解標註的配置類上,在容器啟動後,Spring就會掃描指定包下的bean並將其註入進容器中,如下所示
//聲明3個類,這三個類均位於cn.example.spring.boke同一個包下,其中ExampleA和ExampleB被註解標註,表明它們是bean,需要被註入進容器中,ExampleC是一個普通的類
@Service
public class ExampleA { }
@Component
public class ExampleB { }
public class ExampleC { }
//使用@Configuration註解定義一個配置類,在該配置類上,使用@ComponentScan註解指定包掃描路徑為cn.example.spring.boke,這時,Spring就會掃描該包以及該包的子包下所有符合條件的bean,並將它們註入容器中,該註解等同於在之前提到過的<context:component-scan base-package="..."/>標簽
@Configuration
@ComponentScan("cn.example.spring.boke")
public class Config { }
//啟動容器,註意這裡使用的是AnnotationConfigApplicationContext容器,而非之前的ClassPathXmlApplicationContext容器,而我們也不再需要xml配置文件,實現了完全的基於註解的配置
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);
//列印結果如下,可以看到,容器掃描到了exampleA和exampleB以及我們的配置類config,而忽略了exampleC(其他的bean是Spring隱式自動添加的)
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
config
exampleA
exampleB
3.使用過濾器來自定義組件掃描規則
(1) 預設情況下,Spring僅檢測被@Component、@Repository、@Service、@Controller、@Configuration和以@Component等作為元註解的自定義註解(如:@RestController)標註的類,不過,我們可以通過自定義@ComponentScan註解中的過濾器屬性includeFilters和excludeFilters來修改這一預設行為,如下
//只修改上面例子中的配置類,此處假設我們只掃描被@Service註解標註的類,其自定義過濾規則如下
//includeFilters:要被註入的 excludeFilters:不要被註入的 @ComponentScan.Filter:指定過濾類型
@Configuration
@ComponentScan(basePackages = "cn.example.spring.boke",
includeFilters = @ComponentScan.Filter(Component.class),
excludeFilters = @ComponentScan.Filter(Service.class))
public class Config {
}
//輸出結果如下,可見我們的exampleA已被排除在外
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
config
exampleB
exampleC
過濾類型:
過濾類型 | 說明 |
---|---|
annotation(預設,按照註解過濾) | 如上面例子中的屬性excludeFilters = @ComponentScan.Filter(Service.class),就是排除掉所有被@Service註解標註的類 |
assignable( 按照類型過濾) | 例如:excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ExampleA.class),就是排除掉ExampleA這個類型的bean |
aspectj(按照切麵表達式過濾) | 例如:cn.example..*Service+,這是一個切入點表達式,會對所有符合這個切入點表達式的bean進行過濾 |
regex(按照正則表達式過濾) | 同上,只不過滿足的是正則表達式 |
custom(自定義過濾器) | 實現org.springframework.core.type.TypeFilter介面來自定義過濾器,實現自定義過濾規則 |
(2) 設置@ComponentScan註解中的useDefaultFilters屬性值為false,來禁用預設過濾器,即關閉Spring對於那些預設註解(如@Component等)的自動掃描檢測
4.定義組件的配置元數據
未完待續...