共计 2500 个字符,预计需要花费 7 分钟才能阅读完成。
向 Spring 容器中注册组件是最常见的操作,不过组件注册的方式有很多种,可以选择合适的方式进行注册。
1. @ComponentScan注解
这种方式会将指定包下配置了 @Component、@Controller、@Service、@Repository 的组件注册到容器中。
另外 @ComponentScan 注册组件可以指定和排除某些类或者用注解标记的某些类。
例如:
// 这里的 @Configuration 注解其实也是一个 @Component
@Configuration
@ComponentScan(
value = {"com.amjun.annotation.register.register_01"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes= MyService.class)
}
)
public class Config {}
这种方式一般用于将自己编写的代码进行注册,因为第三方的代码可能不包含这些注解。
2. @Bean注解
@Bean 注解是一个常见的注解,它等价于 xml 配置文件中的
例如:
@Configuration
public class Config {
@Lazy
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public Person person(){
return new Person("zs", 18);
}
}
还可以可以通过 @Scope 配置注册到容器是单例还是多例,通过 @Lazy 控制是否懒加载创建。(spring 默认是直接初始化放入容器中,使用该注解后需要时再创建)
3. @Import注解
@Import 允许将一个或多个类注册到 Spring 容器中,这些类会被作为 Bean 进行管理。关于它的使用,有以下几种方式。
- 导入普通类
该普通类可以是什么都没有标注的类,也可以是自己或第三方标注了 @Configuration 的配置类。
@Configuration
@Import(Person.class)
public class Config {
}
或者:
@Configuration
@Import(TestImportConfig.class)
public class Config {
}
@Configuration
public class TestImportConfig {
@Bean
public Person person(){
return new Person("zs", 18);
}
}
- 使用
ImportSelector动态选择类
ImportSelector 是一个接口,允许根据条件动态选择导入的类。
@Configuration
@Import(MyImportSelector.class)
public class Config_02 {
}
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.amjun.annotation.register.register_03.Person"};
}
}
selectImports 方法返回的类名会被动态加载到应用上下文中,它的返回是一个数组,意味着可以批量注册。
- 使用
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar 是一个接口,通过实现 registerBeanDefinitions 接口,拿到 BeanDefinitionRegistry 进行手动注册。
所有需要注册到 spring 容器中的组件,扫描后会组装成一个个
BeanDefinition,并注册到BeanDefinitionRegistry中,再进行初始化。
@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class Config_03 {
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class);
registry.registerBeanDefinition("person", beanDefinition);
}
}
4. FactoryBean接口
FactoryBean 是 spring 提供的特殊接口,实现了 FactoryBean 接口的类,从 spring 容器中获取时,不是返回对象本身,而是 getObject() 方法返回的对象。这就提供了一种扩展的可能,可以在这个方法里定制创建复杂的逻辑。
@Configuration
public class Config {
@Bean
public PersonFactoryBean person(){
return new PersonFactoryBean();
}
}
public class PersonFactoryBean implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception {
return new Person("lisi", 100);
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
}
提醒:本文发布于351天前,文中所关联的信息可能已发生改变,请知悉!