本节描述一个通过扫描类路径来隐式检测候选组件的选项。
1 @component
- @Component 通常是一些管理组件的注释
- @Repository 是实现存储库角色或原型(也称为数据访问对象或DAO)的任何类的标记。该标记的用途之一是异常的自动翻译,如异常翻译中所述。
- @service 注释服务
- @controller 注释控制器
你可以用@Component来注释你的组件类,但是,通过用@Repository、@Service或@Controller来注释它们,你的类更适合由工具处理或与方面关联。
2 使用元注释和组合注释
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
// ...
}
3 自动检测类和注册Bean定义
@configutation
@compontscan
@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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example"/>
</beans>
4 使用过滤器自定义扫描
默认情况下,带有@Component、@Repository、@Service、@Controller、@Configuration注解的类,或者带有@Component注解的自定义注解是唯一检测到的候选组件.
但是,您可以通过应用自定义筛选器来修改和扩展此行为。将它们添加为@ComponentScan注释的includeFilters或excludeFilters属性
@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>
5 命名自动检测的组件
6 使用JSR 330标准注释
Spring提供了对JSR-330标准注释(依赖注入)的支持。以与Spring注释相同的方式扫描这些注释。要使用它们,需要在类路径中有相关的jar文件。
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.0</version>
</dependency>
你可以用@jakarta.inject代替@Autowired。注入如下:
import jakarta.inject.Inject;
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
public void listMovies() {
this.movieFinder.findMovies(...);
// ...
}
}
@Named和@ManagedBean:与@Component注释等价的标准
JSR-330标准注释的限制: