The IoC Container 1.10(1.10.1-1.
1.10. Classpath Scanning and Managed Components
1.10.1. @Component and Further Stereotype Annotations
@Component is a generic stereotype for any Spring-managed component. @Repository, @Service, and @Controller are specializations of @Component for more specific use cases (in the persistence, service, and presentation layers, respectively).
四个注解@Component,@Repository,@Service 和 @Controller,用来注解需要Spring Container管理的bean,类似xml中的bean元素。被注解的类会由Spring Container进行管理。@Repository,@Service 和 @Controller根据名称,就可以看出他们用途(持久层,业务层,表示层)。@Component是泛化的注解,同时也是用来注解其他三个注解的元注解。
1.10.2. Using Meta-annotations and Composed Annotations
如前所述,@Service注解由@Component元注解标注。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
// ....
}
所以,Spring的很多功能可以使用组合注解达成简化配置的目标。示例如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_SESSION)
public @interface SessionScope {
/**
* Alias for {@link Scope#proxyMode}.
* <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
*/
@AliasFor(annotation = Scope.class)
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
使用如下,这样避免了使用@Scope注解并给其value赋值,另外@SessionScope从名称上就可以看出其语义:
@Service
@SessionScope
public class SessionScopedService {
// ...
}
同时,组合注解可以部分暴露元注解中的属性,@SessionScope暴露了proxyMode属性,使得@SessionScope可以指定代理类型:
@Service
@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
public class SessionScopedUserService implements UserService {
// ...
}
1.10.3. Automatically Detecting Classes and Registering Bean Definitions
基于注解的配置方式,支持自动检测机制,不过需要一些配置。有两种配置方式:一种是java代码方式;一种是xml配置方式。
java代码方式(自动扫描检测org.example包下面的类注册bean定义):
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
...
}
xml配置方式:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example"/>
</beans>
如果需要配置多个包,使用逗号或者空格分隔配置即可。
Spring通过注册AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor来处理基于注解的配置。
1.10.4. Using Filters to Customize Scanning
Spring在自动扫描检测代码时可以配置过滤器来对符合或者不符合条件的类进行过滤。支持include-filter和exclude-filter,功能分别用来包含或者排除符合条件的包。示例如下,表示自动扫描组件时,忽略@Repository注解的类,只扫描类名可以正则匹配".Stub.Repository"的类:
@Configuration
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
public class AppConfig {
...
}
xml配置方式:
<beans>
<context:component-scan base-package="org.example">
<context:include-filter type="regex"
expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
</beans>
filter共有5种类型可以选择,示例中仅给出了两种,其他类型可以参考:
beans-scanning-filters