前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在SpringBoot项目中,我可以说出7种注册bean的方式

在SpringBoot项目中,我可以说出7种注册bean的方式

作者头像
Java进阶之路
发布2022-11-18 15:21:36
1.4K0
发布2022-11-18 15:21:36
举报

前言

Spring和SpringBoot是当前最火的Java开发框架,很多时候我们都会将对象注册到Spring的容器中,将对象交给Spring来管理,那么今天我们就来盘点一下将Bean注册到Spring容器的7种方式。

一:xml配置 + @ImportResource

代码语言:javascript
复制
@Data
public class XmlTestBean {

    private Integer age;

    private String name;
    
}

① 在resource目录下创建Spring的xml配置文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="xmlTestBean" class="com.example.demo.XmlTestBean">
        <property name="age" value="18"/>
        <property name="name" value="xmlBean"/>
    </bean></beans>复制代码

② 利用@ImportResource注解导入xml配置文件

代码语言:javascript
复制
@SpringBootApplication
@ImportResource("classpath:XmlTestBean.xml")
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        XmlTestBean bean = run.getBean(XmlTestBean.class);

        System.out.println(bean);
    }

}

输出结果:

二:@Component + @ComponentScan

① 在需要注册的类上加@Component注解,并且通过@ComponentScan对其进行扫描。

代码语言:javascript
复制
@Component
@Data
public class ComponentTestBean {

    private Integer age = 18;

    private String name = "componentTestBean";
    
}

② 通过@ComponentScan注解扫描有@Component注解的类

代码语言:javascript
复制
@SpringBootApplication(scanBasePackages = "com.example.demo")
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        ComponentTestBean bean = run.getBean(ComponentTestBean.class);

        System.out.println(bean);
    }
}

输出结果:

注:@Service,@Controller,@Repository,@Configuration注解都是@Component注解的复合注解,都归为一类吧。

三: @Configuration + @Bean + @ComponentScan

代码语言:javascript
复制
@Data
public class ConfigurationTestBean {

    private Integer age;

    private String name;
}

① 通过@Configuration和@Bean注解定义bean的信息

代码语言:javascript
复制

@Configuration
public class TestBeanConfiguration {

    @Bean
    public ConfigurationTestBean configurationTestBean(){
        ConfigurationTestBean configurationTestBean = new ConfigurationTestBean();
        configurationTestBean.setAge(18);
        configurationTestBean.setName("configurationTestBean");
        return configurationTestBean;
    }
}

②:利用@ComponentScan注解扫描@Configuration注解

代码语言:javascript
复制
@SpringBootApplication(scanBasePackages = "com.example.demo")
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        ConfigurationTestBean bean = run.getBean(ConfigurationTestBean.class);

        System.out.println(bean);
    }

}

输出结果:

四:实现FactoryBean接口

代码语言:javascript
复制
@Data
public class TestFactoryBean {

    private Integer age;

    private String name;
}

① 实现FactoryBean接口

重写getObject()方法,在getObject()方法中定义bean的信息。

代码语言:javascript
复制
@Component
public class FactoryBeanTest implements FactoryBean<TestFactoryBean> {
    @Override
    public TestFactoryBean getObject() throws Exception {
        TestFactoryBean testFactoryBean = new TestFactoryBean();
        testFactoryBean.setAge(18);
        testFactoryBean.setName("testFactoryBean");
        return testFactoryBean;
    }

    @Override
    public Class<?> getObjectType() {
        return TestFactoryBean.class;
    }
}

② 利用@ComponentScan注解扫描FactoryBean实现类的@Component注解

代码语言:javascript
复制
@SpringBootApplication(scanBasePackages = "com.example.demo")
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        TestFactoryBean bean = run.getBean(TestFactoryBean.class);

        System.out.println(bean);
    }

}

输出结果:

五:实现BeanDefinitionRegistryPostProcessor接口

代码语言:javascript
复制
@Data
public class RegisterTestBean {

    private Integer age;

    private String name;
}

①:实现BeanDefinitionRegistryPostProcessor接口

实现BeanDefinitionRegistryPostProcessor接口,并且重写postProcessBeanDefinitionRegistry方法,利用BeanDefinitionBuilder构建BeanDefinition,然后利用BeanDefinitionRegistry将bean进行注册。

代码语言:javascript
复制
@Component
public class RegisterBeanTest implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinitionBuilder beanDefinitionBuilder = 
                BeanDefinitionBuilder.genericBeanDefinition(RegisterTestBean.class);

        beanDefinitionBuilder.addPropertyValue("age",18);
        beanDefinitionBuilder.addPropertyValue("name","registerTestBean");

        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        
        registry.registerBeanDefinition("registerTestBean",beanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

注:也可以在postProcessBeanFactory方法中实现相关的逻辑,因为在这里ConfigurableListableBeanFactory其实也是BeanDefinitionRegistry类型,可以进行强转。

②利用@ComponentScan注解扫描BeanDefinitionRegistryPostProcessor实现类的@Component注解

代码语言:javascript
复制
@SpringBootApplication(scanBasePackages = "com.example.demo")
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        RegisterTestBean bean = run.getBean(RegisterTestBean.class);

        System.out.println(bean);
    }

}

输出结果:

六:实现BeanFactoryPostProcessor接口

① 实现BeanFactoryPostProcessor接口,利用BeanDefinitionBuilder构建bean的信息,然后通过BeanDefinitionRegistry将bean注册到Spring容器中。

代码语言:javascript
复制
@Data
public class BeanFactoryProcessorTestBean {

    private Integer age;

    private String name;
}
代码语言:javascript
复制
@Component
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        
        if (configurableListableBeanFactory instanceof BeanDefinitionRegistry){
            BeanDefinitionBuilder beanDefinitionBuilder =
                    BeanDefinitionBuilder.genericBeanDefinition(BeanFactoryProcessorTestBean.class);

            beanDefinitionBuilder.addPropertyValue("age",18);
            beanDefinitionBuilder.addPropertyValue("name","BeanFactoryProcessorTestBean");

            AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)configurableListableBeanFactory;
            registry.registerBeanDefinition("beanFactoryProcessorTestBean",beanDefinition);
        }
    }
}

② 利用@ComponentScan注解扫描BeanFactoryPostProcessor实现类的@Component注解

代码语言:javascript
复制
@SpringBootApplication(scanBasePackages = "com.example.demo")
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);

        BeanFactoryProcessorTestBean bean = run.getBean(BeanFactoryProcessorTestBean.class);

        System.out.println(bean);
    }
}

输出结果:

七:通过@Import注解

@Import注解有四种用法

① import一个普通的类

② import ImportSelector接口的实现类

③ import DeferredImportSelector接口的实现类

④ import ImportBeanDefinitionRegistrar接口的实现类

注:关于@Import注解 ,细讲的话篇幅会过长,如果你还对@Import注解有所疑问,那么可以去看我的另外一篇文章 @Import注解的使用和原理,相信会对你有所帮助

最后

如果有任何疑问,欢迎在下方评论区留言。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java进阶之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档