0

0

Spring Boot 工厂模式下实现组件自动注入的正确实践

碧海醫心

碧海醫心

发布时间:2025-12-26 19:50:10

|

294人浏览过

|

来源于php中文网

原创

Spring Boot 工厂模式下实现组件自动注入的正确实践

本文介绍如何在 spring boot 的工厂模式中避免通过方法参数传递依赖,利用 spring 容器手动完成新创建对象的依赖注入,从而保持接口稳定、提升可维护性与扩展性。

在基于工厂模式(如 NotificationFactory)构建多态通知组件时,一个常见痛点是:由工厂 new 出的实例(如 SMSNotification)无法直接使用 @Autowired 注入 Spring 管理的 Bean(如 Environment),因为它们脱离了 Spring 容器的生命周期管理——此时 env 字段为 null。若采用“将 Environment 作为参数传入 notifyUser(Environment)”的方式,虽能临时解决,却违背了接口契约稳定性原则:每新增一个依赖,就必须修改 Notification 接口及全部实现类,导致高耦合、低内聚,严重损害可维护性与可扩展性。

✅ 正确解法是:让 Spring 主动参与工厂创建的对象初始化过程,即在对象实例化后,交由 Spring 容器执行属性注入(Autowiring)。核心思路如下:

  1. 确保 Spring 上下文已启动:使用 SpringApplication.run() 启动应用,而非直接 new NotificationService();
  2. 获取 Spring 的底层 Bean 工厂:注入 DefaultListableBeanFactory(实现了 AutowireCapableBeanFactory);
  3. 在工厂中调用 autowireBeanProperties():对每个 new 出的实例执行按名称(AUTOWIRE_BY_NAME)或类型(AUTOWIRE_BY_TYPE)的依赖注入;
  4. 在具体实现类中自由使用 @Autowired:无需修改接口,新增依赖只需在类中声明并标注 @Autowired 即可。

以下是关键代码实现:

Catimind
Catimind

专为行业应用打造的AI生产力工具

下载
// NotificationService.java —— 启动入口 & 工厂调用方
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;

public class NotificationService {
    @Autowired
    private DefaultListableBeanFactory beanFactory;

    public static void main(String[] args) {
        SpringApplication.run(NotificationService.class, args); // ✅ 必须通过 Spring 启动
    }

    @jakarta.annotation.PostConstruct
    public void testNotifications() {
        NotificationFactory factory = new NotificationFactory(beanFactory);
        Notification notification = factory.createNotification("EMAIL");
        notification.notifyUser(); // 输出含 Environment 信息
    }
}
// NotificationFactory.java —— 支持自动注入的工厂
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

public class NotificationFactory {
    private final DefaultListableBeanFactory beanFactory;

    public NotificationFactory(DefaultListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public Notification createNotification(String channel) {
        if (channel == null || channel.isEmpty()) return null;

        Notification notification;
        switch (channel.toUpperCase()) {
            case "SMS":     notification = new SMSNotification(); break;
            case "EMAIL":   notification = new EmailNotification(); break;
            case "PUSH":    notification = new PushNotification(); break;
            default: throw new IllegalArgumentException("Unknown channel: " + channel);
        }

        // ✅ 关键:委托 Spring 完成依赖注入
        beanFactory.autowireBeanProperties(
            notification,
            AutowireCapableBeanFactory.AUTOWIRE_BY_NAME,
            false // false 表示不调用初始化回调(如 @PostConstruct),如需可设为 true
        );
        return notification;
    }
}
// EmailNotification.java —— 自由声明依赖,无需改接口
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component; // 可选:若后续需被其他 Bean 直接注入,建议加

public class EmailNotification implements Notification {
    @Autowired
    private Environment env; // ✅ 自动注入成功

    @Autowired
    private SomeOtherService service; // ✅ 新增依赖?只需在此添加,无需动接口!

    @Override
    public void notifyUser() {
        System.out.println("Sending email via " + env.getActiveProfiles()[0]);
        if (service != null) service.send();
    }
}

⚠️ 注意事项:

  • autowireBeanProperties() 仅注入字段(@Autowired / @Value),不触发 @PostConstruct、InitializingBean.afterPropertiesSet() 或 @Bean(initMethod=...);如需完整生命周期支持,可改用 beanFactory.initializeBean(notification, "beanName")(需配合 createBean() 或自定义 BeanName);
  • 所有被注入的依赖(如 Environment、SomeOtherService)必须已是 Spring 容器中的单例 Bean;
  • 若 Notification 实现类本身也需被 Spring 管理(如作为 @Service 被其他组件注入),应避免 new 创建,而改用 @Qualifier + ObjectProvider 或策略模式 + ApplicationContext.getBean();
  • 工厂类 NotificationFactory 不必被 Spring 管理(即无需 @Component),因其职责是创建非托管对象并交由 Spring 注入——这正是“混合生命周期管理”的典型场景。

总结:通过 DefaultListableBeanFactory.autowireBeanProperties(),我们以极小侵入性代价,将 Spring 的 DI 能力延伸至工厂动态创建的对象上。它既规避了接口频繁变更的维护成本,又保留了 @Autowired 的简洁性与可读性,是 Spring Boot 中工厂模式与依赖注入协同落地的最佳实践之一。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

98

2025.08.06

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

135

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

382

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

61

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

4

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

1

2025.12.24

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

226

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

430

2024.03.01

虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

25

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2万人学习

C# 教程
C# 教程

共94课时 | 5.3万人学习

Java 教程
Java 教程

共578课时 | 38万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号