spring容器帮我们管理bean,因此需要将bean注册在spring容器中,而bean可以通过xml或者注解的方式进行注册,基于xml的配置一般是通过
、
等xml标签配合进行配置,然后由spring容器扫描xml文件进行注册;基于注解的注册主要是通过几种spring定义的注解进行配置,同样是由spring容器扫描并创建一些bean注册到容器中。
方式一:
最常见的@Controller、@Service、@Component、@Repository,只有知道spring就懂这几个注解的作用。
方式二:
使用@Configuration
和@Bean
结合
被@Configuration
注解标识的类自动获得@Component
的特性,因为该注解本身也是使用了@Component
注解,具体可以查看@Configuration
的源码定义,并且该类会作为spring的一个配置类,在创建该类型的bean
时,spring会扫描当中所有@Bean
注解标注的方法,并自动执行,返回值自动注册在容器中,默认使用方法名作为bean的name。也可以通过提供@Bean
的value值或设置bean的name属性来给bean起名字。
方式三:
使用@ComponentScan
注解自动注册
该注解和在xml中配置
是类似的,通过在@Component
或者相关注解(比如@Controller
、@Configuration
、@Service
都是)标注的类上使用@ComponentScan
注解,spring会根据指定的扫描包路径进行扫描,自动创建所有标有@Component相关注解的类的实例,并将其注册到spring容器中,如果是@Configuration标注的,还会执行其中的@Bean方法。
方式四:
使用@Import注解导入某个类注册到spring容器中
通过在配置类上标注@Import注解,可以快速创建某个类的实例,并导入到spring容器中。
1: @Import 使用ImportSelector 批量导入:
具体方法是指定@Import的值为一个实现了ImportSelector
接口的类,该类重写selectImports
方法,selectImports
方法返回值为一个String数组,这个数组包含要导入的全限定类名。使用了ImportSelector不会将ImportSelector实现类导入,只会将selectImports方法返回的数组指定的类导入。
class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"java.lang.String"};
}
}
@Configuration
@Import({MyImportSelector.class})
class BeanConfig {
}
2:@Import 使用ImportBeanDefinitionRegistrar
自定义一个ImportBeanDefinitionRegistrar类,实现ImportBeanDefinitionRegistrar
接口,重写registerBeanDefinitions
方法,通过参数registry
可以注册bean,比如:
class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//创建一个BeanDefinition对象
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Book.class);
//注册一个名为xixi的BeanDefinition
registry.registerBeanDefinition("xixi", rootBeanDefinition);
}
}
@Configuration
@Import({MyImportBeanDefinitionRegistrar.class})
class BeanConfig {
}
同样是使用@Import注解将ImportBeanDefinitionRegistrar导入,同样是只会将registerBeanDefinitions方法中注册的bean注册,不会将ImportDefinitionRegistrar这个类注册进来。
方式五:
使用FactoryBean注册bean,实现FactoryBean接口
spring判断@Bean注解的方法的返回值是一个工厂Bean,会执行工厂bean的getObject方法获得一个实例,并注册到容器中,如果是单例,则只注册一次。而不是将FactoryBean的实现类注册进来。如果想要获得工厂bean本身这个实例,可以在获取bean的时候指定的bean name前加上“&”前缀,如context.getBean("&bean")