问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Spring依赖注入详解:从入门到实战

创作时间:
作者:
@小白创作中心

Spring依赖注入详解:从入门到实战

引用
1
来源
1.
https://cloud.tencent.com/developer/article/1889640

Spring框架的核心特性之一就是依赖注入(Dependency Injection,简称DI),它使得组件之间的依赖关系可以由容器来管理,而不是在代码中硬编码。本文将从入门到深入,详细讲解Spring中的依赖注入机制,包括依赖注入的基本概念、实现方式以及数据类型注入等内容。

1. Bean的依赖注入入门

1.1 基本概念

在Spring框架中,依赖注入是通过控制反转(Inversion of Control,简称IoC)容器来实现的。IoC容器负责管理应用程序中的对象(即Bean),并处理它们之间的依赖关系。

1.2 创建UserService

假设我们有一个UserService接口,它需要调用UserDaosave()方法。在没有使用Spring的情况下,我们通常会在UserService的实现类中直接创建UserDao的实例:

public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        UserDao userDao = new UserDaoImpl();
        userDao.save();
    }
}

但是,使用Spring后,我们可以将UserDao的创建权交给Spring容器:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.xdr630.service.Impl.UserServiceImpl"></bean>

然后在测试类中从Spring容器中获取UserService实例:

public class UserController {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

2. Bean的依赖注入分析

在上述例子中,UserServiceUserDao都存在于Spring容器中。为了更好地解耦,我们希望在Spring容器内部完成它们之间的依赖关系。具体来说,就是将UserDao注入到UserService中。

3. Bean的依赖注入概念

依赖注入(Dependency Injection)是Spring框架核心IoC的具体实现。在使用Spring之前,组件之间的依赖关系通常需要在代码中硬编码。而使用Spring后,这些依赖关系可以由Spring容器来管理,从而实现真正的解耦。

4. Bean的依赖注入方式

4.1 构造方法注入

构造方法注入是最直接的方式。我们可以在UserServiceImpl中添加一个有参构造方法:

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.save();
    }
}

然后在配置文件中使用<constructor-arg>标签进行注入:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.xdr630.service.Impl.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

4.2 Setter方法注入

Setter方法注入是另一种常见的注入方式。我们可以在UserServiceImpl中添加一个setUserDao方法:

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.save();
    }
}

然后在配置文件中使用<property>标签进行注入:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.xdr630.service.Impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>

4.3 P命名空间注入

P命名空间注入本质上也是Setter方法注入,但配置起来更加方便。首先需要在配置文件中引入P命名空间:

xmlns:p="http://www.springframework.org/schema/p"

然后可以直接在<bean>标签中使用p:前缀进行注入:

<bean id="userService" class="com.xdr630.service.Impl.UserServiceImpl" p:userDao-ref="userDao"/>

5. Bean的依赖注入的数据类型

除了对象引用,Spring还支持普通数据类型、集合数据类型等的注入。

5.1 普通数据类型的注入

假设UserDao需要一些基本属性,如用户名和年龄:

public class UserDaoImpl implements UserDao {
    private String username;
    private int age;
    public void setUsername(String username) {
        this.username = username;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public void save() {
        System.out.println("username=" + username + "\n" + "age=" + age);
        System.out.println("save running......");
    }
}

可以在配置文件中使用<property>标签进行注入:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl">
    <property name="username" value="xdr"/>
    <property name="age" value="22"/>
</bean>

5.2 集合数据类型的注入

5.2.1 List类型的注入

假设UserDao需要一个List<String>类型的属性:

public class UserDaoImpl implements UserDao {
    private List<String> strList;
    public void setStrList(List<String> strList) {
        this.strList = strList;
    }
    public void save() {
        System.out.println(strList);
        System.out.println("save running......");
    }
}

可以在配置文件中使用<list>标签进行注入:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl">
    <property name="strList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
            <value>ccc</value>
        </list>
    </property>
</bean>

5.2.2 Map类型的注入

假设UserDao需要一个Map<String, User>类型的属性:

public class UserDaoImpl implements UserDao {
    private Map<String, User> userMap;
    public void setUserMap(Map<String, User> userMap) {
        this.userMap = userMap;
    }
    public void save() {
        System.out.println(userMap);
        System.out.println("save running......");
    }
}

可以在配置文件中使用<map>标签进行注入:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl">
    <property name="userMap">
        <map>
            <entry key="u1" value-ref="user1"></entry>
            <entry key="u2" value-ref="user2"></entry>
        </map>
    </property>
</bean>
<bean id="user1" class="com.xdr630.domain.User">
    <property name="name" value="tom"/>
    <property name="addr" value="beijing"/>
</bean>
<bean id="user2" class="com.xdr630.domain.User">
    <property name="name" value="jerry"/>
    <property name="addr" value="shanghai"/>
</bean>

5.2.3 Properties类型的注入

假设UserDao需要一个Properties类型的属性:

public class UserDaoImpl implements UserDao {
    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    public void save() {
        System.out.println(properties);
        System.out.println("save running......");
    }
}

可以在配置文件中使用<props>标签进行注入:

<bean id="userDao" class="com.xdr630.dao.impl.UserDaoImpl">
    <property name="properties">
        <props>
            <prop key="p1">ppp1</prop>
            <prop key="p2">ppp2</prop>
            <prop key="p3">ppp3</prop>
        </props>
    </property>
</bean>

6. 引入其他配置文件(分模块开发)

在实际开发中,Spring的配置内容可能非常庞大,因此可以将配置拆分成多个配置文件。例如:

<import resource="applicationContext-xxx.xml"/>

这样,只需要加载主配置文件,其他配置文件就会被自动加载。

7. Spring的重点配置

在Spring配置文件中,<bean>标签是最核心的配置元素,它包含了以下重要属性:

  • id:Bean的唯一标识
  • class:Bean的全限定名
  • scope:Bean的作用范围,常用的是Singleton(默认)和prototype

<property>标签用于属性注入,可以注入普通属性值或对象引用值。<constructor-arg>标签用于构造方法注入。<import>标签用于导入其他配置文件。

通过本文的讲解,相信读者已经对Spring框架中的依赖注入有了全面的了解。掌握这些知识,将有助于开发出更加灵活、可维护的Java应用程序。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号