SpringBoot中注册Bean的10种方式总结

❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基

在Spring Boot应用中,Bean是构成应用的核心组件。Spring容器负责管理这些Bean,包括它们的创建、配置、组装、管理和销毁。在Spring Boot中,有多种方式可以注册Bean,让Spring容器能够管理它们。本文将详细介绍这些不同的注册方式,并给出相应的示例代码和适用场景。

1. 使用@Component及其派生注解

@Component是一个泛化的注解,用于标记一个类作为Spring容器管理的Bean。Spring Boot在启动时会自动扫描这些注解,并将标记的类注册为Bean。@Service@Repository@Controller@Component的派生注解,分别用于标记服务层、持久层和控制器层的组件。

代码:

@Service
public class MyService {
    // 服务逻辑...
}

适用场景:

  • 当你需要让Spring容器管理一个自定义的类的实例时,可以使用@Component及其派生注解。

2. 使用@Bean注解

在配置类中,可以使用@Bean注解来声明一个Bean。这个方法会返回一个对象,该对象会被注册为一个Bean,并且方法名默认作为Bean的ID。

代码:

@Configuration
public class AppConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

适用场景:

  • 当你需要在Java配置类中显式声明Bean时,可以使用@Bean注解。
  • 当你需要注册一个非自定义的类到容器中时.

3. 使用@Import注解

@Import注解可以用于导入其他配置类,这样可以将分散在不同配置类中的Bean集中管理。

代码:

// 定义一个配置类  
@Configuration  
public class OtherConfig {  
    @Bean  
    public OtherBean otherBean() {  
        return new OtherBean();  
    }  
}  
  
// 在主配置类中导入OtherConfig  
@Configuration  
@Import(OtherConfig.class)  
public class AppConfig {  
    // 其他Bean定义...  
}

适用场景:

  • 当你需要将多个配置类分散管理,但又想在一个主配置类中集中导入它们时,可以使用@Import注解。

4. 使用ImportSelector接口

ImportSelector接口允许你根据条件选择性地导入配置类。实现这个接口后,可以返回需要导入的配置类的全类名数组。

// 实现ImportSelector接口  
public class MyImportSelector implements ImportSelector {  
    @Override  
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {  
        // 根据条件选择导入的配置类  
        return new String[]{OtherConfig.class.getName()};  
    }  
}  
  
// 在主配置类中使用@Import注解导入ImportSelector  
@Configuration  
@Import(MyImportSelector.class)  
public class AppConfig {  
    // 其他Bean定义...  
}

适用场景:

  • 当你需要根据不同条件导入不同配置时,可以使用ImportSelector接口。

5. 使用ImportBeanDefinitionRegistrar接口

ImportBeanDefinitionRegistrar接口允许你在导入配置类时注册额外的Bean定义。这在你需要编程式地注册Bean时非常有用。

// 实现ImportBeanDefinitionRegistrar接口  
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {  
    @Override  
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {  
        // 注册一个Bean定义  
        RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);  
        registry.registerBeanDefinition("myBean", beanDefinition);  
    }  
}  
  
// 在主配置类中使用@Import注解导入ImportBeanDefinitionRegistrar  
@Configuration  
@Import(MyImportBeanDefinitionRegistrar.class)  
public class AppConfig {  
    // 其他Bean定义...  
}

适用场景:

  • 当你需要在导入配置类时动态注册Bean时,可以使用ImportBeanDefinitionRegistrar接口。

6. 使用FactoryBean接口

FactoryBean接口允许你定义一个工厂Bean,这个工厂Bean会返回一个对象实例。当你需要控制Bean的创建过程时,可以使用这种方式。

// 定义一个FactoryBean,用于创建MyBean实例  
public class MyFactoryBean implements FactoryBean<MyBean> {  
    @Override  
    public MyBean getObject() throws Exception {  
        // 创建并返回MyBean实例  
        return new MyBean();  
    }  
  
    @Override  
    public Class<?> getObjectType() {  
        // 返回FactoryBean创建的Bean类型  
        return MyBean.class;  
    }  
  
    @Override  
    public boolean isSingleton() {  
        // 返回FactoryBean创建的Bean是否为单例  
        return true;  
    }  
}  
  
// 在配置类中使用@Bean注解注册FactoryBean  
@Configuration  
public class AppConfig {  
    @Bean  
    public FactoryBean<MyBean> myFactoryBean() {  
        return new MyFactoryBean();  
    }  
}

适用场景:

  • 当你需要控制Bean的创建过程,或者返回一个复杂对象的实例时,可以使用FactoryBean接口。

7. 使用@ComponentScan注解

@ComponentScan注解用于指定Spring Boot启动时扫描的包路径。Spring容器会扫描这些包路径下的类,并将标记了@Component@Service@Repository@Controller等注解的类注册为Bean。

// 定义一个Service类,并使用@Service注解标记  
@Service  
public class MyService {  
    // 服务逻辑...  
}  
  
// 在主配置类中使用@ComponentScan注解指定扫描的包路径  
@Configuration  
@ComponentScan(basePackages = "com.example.myapp")  
public class AppConfig {  
    // 其他Bean定义...  
}

适用场景:

  • 当你需要让Spring Boot在启动时扫描特定的包路径,并注册其中的Bean时,可以使用@ComponentScan注解。

8. 自动配置(Spring Boot Starter)

Spring Boot的自动配置是通过spring.factories文件实现的。你可以创建一个自定义的starter,并在spring.factories文件中指定自动配置类。这样,当其他项目添加你的starter依赖时,Spring Boot会自动配置相关的Bean。

创建自定义的starter时,需要在src/main/resources/META-INF目录下创建一个spring.factories文件,并指定自动配置类。

spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\  
com.example.demo.autoconfigure.DemoAutoConfiguration

自动配置类:

@Configuration  
public class DemoAutoConfiguration {  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
    // 其他配置...  
}

适用场景:

  • 当你需要为Spring Boot应用提供一套默认的、开箱即用的配置时,可以创建一个自定义的starter,并使用自动配置来注册Bean。

9. 使用@Enable*注解

Spring Boot提供了许多@Enable*注解,如@EnableWebMvc@EnableCaching等。这些注解通常会通过导入一个或多个配置类来启用特定的功能,并注册相关的Bean。

// 在配置类上使用@EnableWebMvc注解启用Spring MVC  
@Configuration  
@EnableWebMvc  
public class WebMvcConfig implements WebMvcConfigurer {  
    // 配置Spring MVC...  
  
    @Override  
    public void addViewControllers(ViewControllerRegistry registry) {  
        // 注册视图控制器...  
    }  
}

适用场景:

  • 当你需要使用Spring Boot提供的特定功能,并且这些功能是通过@Enable*注解来启用的时,可以使用这些注解来注册相关的Bean。

自定义一个@Enable:

自定义一个@Enable类似的功能要创建一个注解,并使用@Import注解来导入一个配置类或选择器。这样,当你在应用程序中使用这个自定义的@Enable注解时,Spring会自动导入并注册相关的配置或组件

// 自定义注解  
@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)  
@Import(MyEnableConfiguration.class)  
public @interface EnableMyFeature {  
    // 可以添加属性来配置功能  
}  
  
// 配置类  
@Configuration  
public class MyEnableConfiguration {  
    @Bean  
    public MyFeatureBean myFeatureBean() {  
        return new MyFeatureBean();  
    }  
}  
  
// 使用自定义注解  
@SpringBootApplication  
@EnableMyFeature  
public class MyApplication {  
    public static void main(String[] args) {  
        SpringApplication.run(MyApplication.class, args);  
    }  
}

10. 编程式地注册Bean(使用ApplicationContext

某些情况下需要在运行时编程式地注册Bean。可以通过获取ApplicationContext的引用,并使用其提供的API来注册Bean。

@Component  
public class MyBeanRegistrar implements ApplicationContextAware {  
    private ApplicationContext applicationContext;  
  
    @Override  
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
        this.applicationContext = applicationContext;  
        registerBean();  
    }  
  
    private void registerBean() {  
        RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);  
        applicationContext.getBeanFactory().registerSingleton("myBean", beanDefinition);  
    }  
}

适用场景:

  • 当你需要在运行时动态地注册Bean时,可以使用编程式地注册Bean的方式。这种方式比较罕见,通常只在特定的场景下使用。

关注公众号[码到三十五]获取更多技术干货 !

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot注册过滤器有两方式。第一方式是在WebConfig类使用FilterRegistrationBean来注册过滤器。需要注意的是,如果要注册的过滤器没有使用@Component注解标识为Spring Bean,那么WebConfig将不会生效,导致Spring Boot启动失败。\[1\] 另一方式是通过Java代码手动注册过滤器。如果引入的第三方jar包的过滤器没有使用@Component标识为Spring Bean,那么这个过滤器也不会生效。此时,需要使用java代码去注册这个过滤器。\[2\] 总结来说,无论是使用FilterRegistrationBean注册过滤器,还是使用原生servlet注解定义过滤器,本质上都是通过FilterRegistrationBean来注册自定义过滤器。\[3\]所以,如果在Spring Boot注册过滤器失败,可能是因为过滤器没有正确标识为Spring Bean,或者没有正确配置FilterRegistrationBean。请检查过滤器的注解和配置,确保正确注册过滤器。 #### 引用[.reference_title] - *1* *2* [springboot 自定义过滤器](https://blog.csdn.net/weixin_42029738/article/details/127718063)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Springboot 过滤器](https://blog.csdn.net/yangyifan0/article/details/128089956)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码到三十五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值