• Spring Framework IoC依赖注入-按Bean类型注入



    theme: smartblue

    Spring Framework 作为一个领先的企业级开发框架,以其强大的依赖注入(Dependency Injection,DI)机制而闻名。DI使得开发者可以更加灵活地管理对象之间的关系,而不必过多关注对象的创建和组装。在Spring Framework中,依赖注入可以分为两种类型:根据Bean名称注入、根据Bean类型注入,在本文中,我们将聚焦于 Spring 中的一种依赖注入方式——按类型注入,并通过一个简单的示例来说明其使用和优势。

    什么是依赖注入?

    don’t call us, we’ll call you

    依赖注入是一种先进的设计思想,它通过外部注入依赖对象来实现组件之间的松耦合。在 Spring 框架中,依赖注入的核心实现便是通过控制反转(Inversion of Control,IoC)容器。IoC 容器负责实例化、配置和组装应用中的对象,并在需要时将它们智能地注入到其他对象中。相较于传统的面向对象思想,当业务代码变得复杂时,通过直接使用 new 进行对象构造对象间的关系,容易导致代码耦合度的上升。Spring 通过控制反转巧妙地解决了这一问题,运用了好莱坞原则的理念:不要给我们打电话,我们会给你打电话。这种思想使得代码更加灵活、可维护,并促使了更优雅的代码结构。

    pexels-masood-aslami-19012241.jpg


    Spring 中的依赖注入

    在 Spring 中,依赖注入有多种方式,包括构造函数注入、Setter 方法注入、接口注入等。示例中展示的是一种基于 XML 配置的 Setter 方法注入。

    构造函数注入的案例:

    public class UserService {
    
        private final EmailService emailService;
    
        // 构造函数注入
        public UserService(EmailService emailService) {
            this.emailService = emailService;
        }
    
        public void sendWelcomeEmail(String username) {
            String message = "Welcome, " + username + "!";
            emailService.sendEmail("welcome@example.com", message);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Setter 方法注入的案例:

    public class NotificationServiceClient {
    
        private NotificationService notificationService;
    
        // Setter 方法注入
        public void setNotificationService(NotificationService notificationService) {
            this.notificationService = notificationService;
        }
    
        public void sendNotification(String message) {
            notificationService.notifyUser(message);
        }
    }
    ```java
    
    ### 接口注入的案例:
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    public class LoggingService {

    private Logger logger;
    
    // 接口注入
    public void setLogger(Logger logger) {
        this.logger = logger;
    }
    
    public void logMessage(String message) {
        logger.log(message);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    }

    
    在本文中以知名IP:小马哥在《小马哥讲 Spring 核心编程思想》中使用的代码案例展开。
    
    Github源码:
    
    [GeekTime](https://gitee.com/geektime-geekbang/geekbang-lessons.git)
    
    dependency-injection-context.xml
    
    ```xml
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    dependency-lookup-context.xml:

    
    <beans
            xmlns="http://www.springframework.org/schema/beans"
            xmlns:context="http://www.springframework.org/schema/context"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
    
    
    
    
        
        
        
        <bean id="user" class="org.geekbang.thinking.in.spring.ioc.overview.domain.User">
            <property name="id" value="1"/>
            <property name="name" value="小马哥"/>
            <property name="city" value="HANGZHOU"/>
            <property name="workCities" value="BEIJING,HANGZHOU"/>
            <property name="lifeCities">
                <list>
                    <value>BEIJINGvalue>
                    <value>SHANGHAIvalue>
                list>
            property>
            <property name="configFileLocation" value="classpath:/META-INF/user-config.properties"/>
        bean>
    
        
        
        
        <bean id="superUser" class="org.geekbang.thinking.in.spring.ioc.overview.domain.SuperUser" parent="user"
              primary="true">
            <property name="address" value="杭州"/>
        bean>
    
        <bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
            <property name="targetBeanName" value="user"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在这个例子中,我们通过 XML 配置文件导入了 dependency-lookup-context.xml,并配置了一个名为 userRepositoryUserRepository Bean,并通过 autowire=“byType” 实现了自动按类型注入。这样,Spring 容器会在运行时查找并注入与 UserRepository 类型匹配的 User 对象。

    UserRepository 类

    public class UserRepository {
    
        /**
         * 自定义Bean
         */
        private Collection<User> users;
    
        public Collection<User> getUsers() {
            return users;
        }
    
        public void setUsers(Collection<User> users) {
            this.users = users;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    UserRepository 类中定义了一个名为 users 的集合属性,并提供了相应的 Getter 和 Setter 方法。通过 Setter 方法,我们可以在 Spring 容器中配置的时候注入一组 User 对象。

    主程序

    public static void main(String[] args) {
        // 配置 XML 配置文件
        // 启动 Spring 应用上下文
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
        UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
        System.out.println(userRepository.getUsers());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在主程序中,我们通过 ClassPathXmlApplicationContext 加载了 XML 配置文件,获取了名为 userRepositoryUserRepository Bean,并输出了其中包含的 User 对象集合。

    结论

    通过这个简单的示例,我们了解了 Spring Framework 中依赖注入的基本原理。依赖注入通过控制反转容器实现,使得应用程序中的对象不再负责管理自己的依赖关系,而是由 IoC 容器负责。这种设计模式降低了组件之间的耦合度,提高了代码的可测试性和可维护性,是 Spring 成功的关键之一。在实际项目中,我们可以根据需求选择适合的依赖注入方式,使代码更加清晰、灵活且易于维护。

    后续内容文章持续更新中…

    近期发布。


    关于我

    👋🏻你好,我是Debug.c。微信公众号:种颗代码技术树 的维护者,一个跨专业自学Java,对技术保持热爱的bug猿,同样也是在某二线城市打拼四年余的Java Coder。

    🏆在掘金、CSDN、公众号我将分享我最近学习的内容、踩过的坑以及自己对技术的理解。

    📞如果您对我感兴趣,请联系我。

    若有收获,就点个赞吧,喜欢原图请私信我。

  • 相关阅读:
    直流无刷电机开环调速基于STM32F302R8+X-NUCLEO-IHM07M1(一)
    双11预售在即,小红书品牌如何高效分析竞品?
    用Three.js打造生成式NFT艺术藏品
    掌握MT4交易平台:解决你常见疑惑,提升操作技巧
    机器学习笔记 - Kornia:结合OpenCV的PyTorch框架
    六边形架构浅析
    C++ 构造函数
    xxl-job任务调度2.0.2升级到2.3.0版本,执行器改造过程中经验总结
    mapbox的使用
    ARCGIS---dem生成高程点
  • 原文地址:https://blog.csdn.net/weixin_42313773/article/details/134541814