Spring控制反转(Ioc)和依赖注入(DI)

为什么需要控制反转

我们经常在service层需要调用dao层的方法,在controller层调用service层的方法,在学习spring之前,我们使用 new 对象 的方法进行方法调用

java 复制代码
// dao
public interface UserDao {
    public void save();
}
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("user dao save ...");
    }
}
// service
public interface UserService {
    public void save();
}
public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
    public void save() {
        System.out.println("user service ...");
        userDao.save();
    }
}
  • 业务层需要调用数据层的方法,就需要在业务层new数据层的对象,代码耦合度偏高
  • 为解决这个问题,Spring提出控制反转这一核心概念,使用对象时,在程序中不再使用new产生对象,转换为由"外部"提供对象

控制反转是什么

Spring控制反转(IoC)是一种设计模式,用于将控制权从代码本身转移到外部容器。

  • 控制:对象的创建权
  • 反转:对象的创建权由程序内部(new 对象) 转移到外部(Spring Ioc 容器)
  • 在Spring框架中,我们可以通过配置文件或注解来描述这些对象,并将它们装配到容器中。这样,当我们需要访问某个对象时,我们不再需要显式地创建它,而是可以在容器中查找它并获取对它的引用。

Spring和Ioc的关系

  • IoC是Spring框架的核心概念之一,它通过实现依赖注入(DI)来实现对象之间的解耦和管理。
  • Spring技术对IOC思想进行了实现,他提供了一个容器,称为IOC容器,用来充当IOC思想中的"外部"
  • Spring的IoC容器负责创建、管理和维护应用程序中所需要的对象及其之间的关系。
  • 创建或被管理的对象在IOC容器中统称为 Bean

依赖注入是什么?

依赖注入 即DI(Dependency Injection),它是一种软件设计模式,用于管理对象之间的关系和依赖,在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。

  • 我们可以根据需求建立起依赖关系,如上述代码,业务层需要依赖数据层,UserService就要和UserDao建立依赖关系

依赖注入常见的三种方式

  • 构造函数注入(Constructor Injection):通过构造函数将依赖对象传递给Bean。
  • 属性注入(Setter Injection):通过属性的setter方法将依赖对象注入到Bean中。
  • 注解注入(Annotation Injection):使用注解(如@Autowired、@Resource)注入依赖对象。

修改上述代码,删除service中使用new的方式创建的dao对象

java 复制代码
// service
public interface UserService {
    public void save();
}
public class UserServiceImpl implements UserService {
    private UserDao userDao ;
    public void save() {
        System.out.println("user service ...");
        userDao.save();
    }
}

构造函数注入

  • UserServiceImpl中添加一个构造函数接收一个UserDao对象,并将其分配userDao字段
java 复制代码
    // UserServiceImpl 中添加构造函数
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

可以使用XML配置文件或注解来指定依赖项的注入方式。

此处使用XML配置文件进行构造函数注入

xml 复制代码
<bean id="userService" class="com.example.UserServiceImpl">
    <constructor-arg ref="userDao" />
</bean>
​
<bean id="userDao" class="com.example.UserDao" />
​
  • bean-id :bean的唯一标识名
  • class:指定 bean 的类型,配置bean的全路径类名,与具体java类一致
  • constructor-arg: 来指定构造函数参数,ref 属性指定了依赖的 dao Bean,ref的值与bean的标识名一致

setter注入

在 UserServiceImpl 中添加一个Setter方法接收 UserDao对象,并将其分配给userDao字段

java 复制代码
// 添加set方法
public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

使用XML配置文件进行set注入

xml 复制代码
<bean id="userService" class="com.example.UserServiceImpl">
    <property name="userDao" ref="userDao" />
</bean>
​
<bean id="userDao" class="com.example.UserDao" />
​
  • property: 用于来指定set注入的属性依赖项
  • name:指定要注入的属性名称,Spring的IOC容器在获取到名称后,将首字母大写,前面加set找对应的setUserDao()方法进行对象注入,所以 name的值应与 java类中对应字段的值一致
  • ref:属性指定了依赖的 userDao Bean。Spring将会在IOC容器中找到id为userDao的Bean对象给userService进行注入

注解注入

在上述UserDaoImpl类上添加@Component注解

java 复制代码
@Component("userDao")
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("user dao save ..." );
    }
}
  • @Component:类似注册了一个bean,id为 userDao

在UserServiceImpl 中添加字段注解:@Autowired ,添加类注解@Component

java 复制代码
@Component
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao ;
    public void save() {
        System.out.println("user service ...");
        userDao.save();
    }
}
​

XML配置文件配置组件扫描

xml 复制代码
<context:component-scan base-package="com.example" />
  • 使用<context:component-scan>元素来指定要扫描的包,使Spring容器能够自动检测到带有@Autowired注解的依赖项。

在实际开发中,我们大多数情况下使用注解的方式进行开发

相关推荐
曾令胜6 小时前
excel导出使用arthas动态追踪方法调用耗时后性能优化的过程
spring·性能优化·excel
多云几多6 小时前
Yudao单体项目 springboot Admin安全验证开启
java·spring boot·spring·springbootadmin
摇滚侠8 小时前
Spring Boot 3零基础教程,Spring Intializer,笔记05
spring boot·笔记·spring
兮动人9 小时前
Spring Bean耗时分析工具
java·后端·spring·bean耗时分析工具
MESSIR229 小时前
Spring IOC(控制反转)中常用注解
java·spring
hello 早上好13 小时前
深入 Spring 条件化配置底层:从硬编码到通用注解的实现原理
java·后端·spring
亚林瓜子13 小时前
Spring中Date日期序列化与反序列化中格式设置
java·后端·spring·jackson·date
哞哞不熬夜18 小时前
JavaEE--Spring MVC
spring·java-ee·mvc
Java水解18 小时前
深入剖析Spring Boot依赖注入顺序:从原理到实战
后端·spring
椎49519 小时前
web后端开发——原理
spring boot·spring·mybatis