写点什么

想成为 Spring 大牛?先了解这 6 种添加 Bean 的方式

作者:Java你猿哥
  • 2023-04-04
    湖南
  • 本文字数:2496 字

    阅读完需:约 8 分钟

自动扫描(Component Scanning)

自动扫描是 Spring 容器自动查找并加载 Bean 的一种方式。在 Spring 中,可以使用注解来标记一个类为 Bean,例如使用 @Component、@Service、@Repository 或 @Controller 等注解来标记一个类。在应用程序启动时,Spring 容器会扫描项目中所有被这些注解标记的类,将它们实例化并放入容器中。

@Componentpublic class MyBean {    private String name;    // 省略 getter/setter 方法}
// 在 Spring 配置文件中开启自动扫描<context:component-scan base-package="com.example" />
// 在需要使用 MyBean 的地方注入即可@Autowiredprivate MyBean myBean;
复制代码

优点:自动扫描可以非常方便地将所有需要管理的 Bean 集中在一起,并且不需要手动配置每个 Bean 的信息,减少了代码量和配置时间。

缺点:自动扫描容易将不需要被管理的类也加载进来,导致容器中存在大量无用的 Bean,降低应用程序的性能

XML 配置文件

XML 配置文件是 Spring 最早也是最经典的一种配置方式。在 XML 文件中定义 Bean,指定它们的类名、属性和依赖关系等信息,然后通过配置文件加载器将其加载进 Spring 容器中。

<!-- 在 XML 配置文件中定义 Bean --><bean id="myBean" class="com.example.MyBean">    <property name="name" value="John" /></bean>
复制代码

优点:XML 配置文件能够非常清晰地表达每个 Bean 的信息,包括类名、属性、依赖关系等,方便管理和维护。

缺点:XML 配置文件比较冗长,写起来比较繁琐,而且不太容易维护。同时,由于需要手动编写配置文件,容易出现错误,需要进行额外的测试和调试工作。

Java 配置类

Java 配置类是 Spring 4.0 引入的一种新的配置方式,通过 Java 代码来定义 Bean 的信息,而不是通过 XML 文件。在 Java 配置类中使用 @Configuration 注解来标记这个类是一个配置类,然后使用 @Bean 注解来标记需要被 Spring 容器管理的 Bean。

@Configurationpublic class AppConfig {    @Bean    public MyBean myBean() {        MyBean myBean = new MyBean();        myBean.setName("John");        return myBean;    }}
复制代码

优点:Java 配置类相比 XML 配置文件更加简洁,可以使用 Java 代码来表达 Bean 的信息,提高了可读性和可维护性。

缺点:Java 配置类需要手动编写,编写过程需要一定的 Java 基础知识,同时需要更多的时间和精力。


基于注解的配置

基于注解的配置是一种结合了自动扫描和注解的方式。在这种方式下,我们可以使用特定的注解来指定某个 Bean 的信息,例如使用 @Value 来注入属性值,使用 @Autowired 来注入依赖关系。这种方式比纯粹的自动扫描更加灵活,可以根据实际情况进行定制化配置。

@Componentpublic class MyBean {    @Value("John")    private String name;    // 省略 getter/setter 方法}
@Configurationpublic class AppConfig { // 在配置类中定义需要注入的 Bean @Bean public MyBean myBean() { return new MyBean(); }}
// 在需要使用 MyBean 的地方注入即可@Autowiredprivate MyBean myBean;
复制代码

优点:基于注解的配置相比于 XML 配置文件和 Java 配置类更加简洁,可以通过注解来定义 Bean 的信息,提高了可读性和可维护性。


缺点:基于注解的配置可能会存在注解使用不规范或者忘记注解导致无法注入的问题,需要进行额外的测试和调试工作。

JavaEE 注解

JavaEE 注解是 JavaEE 规范中定义的注解,Spring 支持将这些注解用于定义 Bean 的信息。例如,可以使用 @Resource 来注入依赖关系,使用 @EJB 来注入远程 EJB 等。这种方式相对于其他方式来说比较少用,但是对于使用 JavaEE 技术栈的项目来说,也是一种可以考虑的方式。

@Componentpublic class MyBean {    @Resource(name = "myDependency")    private MyDependency myDependency;    // 省略 getter/setter 方法}
// 在 Spring 配置文件中开启 JavaEE 注解支持<context:annotation-config />
// 在需要注入 MyDependency 的地方定义 Bean@Beanpublic MyDependency myDependency() { return new MyDependency();}
// 在需要使用 MyBean 的地方注入即可@Autowiredprivate MyBean myBean;
复制代码

优点:JavaEE 注解是 JavaEE 规范中定义的注解,具有规范性和通用性。

缺点:JavaEE 注解不是 Spring 核心的一部分,使用起来需要额外的配置和集成工作。

通过实现 BeanFactoryPostProcessor 接口

BeanFactoryPostProcessor 是 Spring 容器提供的扩展点接口之一,可以用于在 Bean 加载完成之后修改 Bean 的属性和行为。可以通过实现 BeanFactoryPostProcessor 接口的方式,在 Bean 加载完成之后将 Bean 放入 Spring 容器中。

@Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        // 创建 BeanDefinition 并将其加入到 BeanFactory 中        BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class)            .addPropertyValue("name", "John")            .getBeanDefinition();        beanFactory.registerBeanDefinition("myBean", beanDefinition);    }}
// 在需要使用 MyBean 的地方注入即可@Autowiredprivate MyBean myBean;
复制代码

优点:通过实现 BeanFactoryPostProcessor 接口可以非常灵活地修改 Bean 的属性和行为,使得 Bean 的管理更加便捷。

缺点:需要了解 Spring 容器的生命周期和扩展点机制,并且需要手动编写 BeanFactoryPostProcessor 的实现代码,对于初学者来说可能有一定的难度。

总结

将 Bean 放入 Spring 容器中的方式有很多种,每种方式都有其优缺点。在实际项目中,需要根据实际情况进行选择和配置,以达到最优的效果。总的来说,自动扫描和基于注解的配置是比较常用的方式,Java 配置类也是一个不错的选择,而 XML 配置文件和 JavaEE 注解则相对不太常用。如果需要对 Bean 进行更加细致的管理和配置,则可以考虑通过实现 BeanFactoryPostProcessor 接口来实现。


用户头像

Java你猿哥

关注

一只在编程路上渐行渐远的程序猿 2023-03-09 加入

关注我,了解更多Java、架构、Spring等知识

评论

发布
暂无评论
想成为 Spring 大牛?先了解这 6 种添加 Bean 的方式_spring_Java你猿哥_InfoQ写作社区