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。

 

posted @   残城碎梦  阅读(156)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
历史上的今天:
2021-11-20 【杂谈Spring】Spring常见问题解决
2021-11-20 【杂谈Spring】Spring中Resource(资源)的获取
2021-11-20 聊聊Spring的缓存及如何自定义缓存
点击右上角即可分享
微信分享提示