Spring注册Bean的方式
@Component
将某个类作为Bean
@Component
public class Helper {
}
还有一些基于@Component进行扩展的注解也能实现,比如@Configuration、@Controller/@RestController、@Service、@Repository等。
@Configuration
public class MyConfig {
}
@Service
public class UserService {
}
@Controller
public class UserController {
}
@RestController
public class UserController {
}
@Repository
public class UserRepository {
}
@Configuration+@Bean
Spring扫描时,解析方法作为Bean
@Configuration
public class MyConfig {
@Bean
public String user() {
return new User();
}
}
@Configuration+@Import
@Import(value = {Helper.class})
@Configuration
public class MyConfig {
}
@ImportResource
导入一个Spring XML配置文件,通过解析该文件注册Bean
@ImportResource("classpath:spring-beans.xml")
@Configuration
public class MyConfig {
}
@Import+ImportSelector接口
第一步:实现ImportSelector接口
@Slf4j
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//当前类的所有注解
Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes();
System.out.println("当前配置类的注解信息:" + annotationTypes);
//不能返回null,不然会报NullPointException
//返回需要导入的组件的全类名数组
return new String[]{User.class.getName()};
}
}
第二步:将@Import(ImportSelector接口的实现类)放在在其他@Configuration标记的类上
@Import(MyImportSelector.class)
@Configuration
public class AppConfig {
}
注意与【@Configuration + @Import】做区分
@Import+ImportBeanDefinitionRegistrar
第一步:实现ImportBeanDefinitionRegistrar接口
@Slf4j
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:当前类的注解信息
* BeanDefinitionRegistry:BeanDefinition注册类;
* 把所有需要添加到容器中的bean;调用
* BeanDefinitionRegistry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
log.info("MyImportBeanDefinitionRegistrar registerBeanDefinitions......");
// 可以判断对象是否已经注册到容器
// boolean definition = registry.containsBeanDefinition("com.knife.example.entity.MyBean");
//指定Bean定义信息
RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
//注册一个Bean,指定bean名
registry.registerBeanDefinition("myBean", beanDefinition);
}
}
第二步:将@Import(ImportBeanDefinitionRegistrar接口的实现类)放在在其他@Configuration标记的类上
@Import(MyImportBeanDefinitionRegistrar.class)
@Configuration
public class AppConfig {
}
BeanFactoryAware
@Component
public class MyBeanFactoryAware implements BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory;
User user = new User();
defaultListableBeanFactory.registerSingleton("user", user);
}
}
BeanDefinitionRegistryPostProcessor
通过注册BeanDefinition来注册Bean
@Component
public class MyBeanDefinition implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// 1.创建BeanDefinition
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
// 2.注册BeanDefinition
beanDefinitionRegistry.registerBeanDefinition("user", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
FactoryBean
通过实现getObject()方法,来注册为Bean
@Component
public class MyFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User(); // Bean 对象
}
@Override
public Class<?> getObjectType() {
return User.class; // Bean 类型
}
//是否单例(默认为true)
//true:这个bean是单例,在容器中只保存一份
//false:多实例,每次获取都会创建一个新的bean;
@Override
public boolean isSingleton() {
return true;
}
}
在Spring扫描时,会先将MyFactoryBean生成Bean对象,不会将User作为Bean。
SmartFactoryBean
通过实现getObject()方法,来注册为Bean;
通过实现isEagerInit()方法,来决定Bean生成的时机。
@Component
public class MySelfFactoryBean implements SmartFactoryBean {
@Override
public Object getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isEagerInit() { // 决定Bean生成的时机:true,初始化时生产Bean;false:调用时,生成Bean
return true;
}
}
当isEagerInit()返回值为true时,在Spring扫描时,就会自动生成Bean。否则,在调用时生成Bean。