spring容器幫我們管理bean,因此需要將bean註冊在spring容器中,而bean可以通過xml或者註解的方式進行註冊,基於xml的配置一般是通過<bean>
、<context:component-scan>
等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中配置<context:component-scan base-package="">
是類似的,通過在@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")