一、IoC控制反转
控制反转(Inversion of Control 简称 IoC) 是一种设计思想,在Java开发中,它将对象的创建和配置控制权从应用程序代码中转移到外部容器中。
在传统的Java SE程序设计中,我们直接在对象内部通过 new 关键字创建对象。基本上是,在哪里使用实例,在哪里 new 一个对象。
IoC 将这一过程外部化,由外部容器来负责这些对象的创建和配置,使得对象不再直接控制其依赖对象的创建。这种做法使得代码之间的依赖关系更加松散,从而提高了代码的灵活性和可维护性。
在 Spring 框架中,IoC容器负责管理应用程序中的对象,包括它们的生命周期、依赖关系和配置。IoC容器通过使用反射和动态代理技术来实现对象的创建和管理。
有控制反转就有控制正转。控制正转可以理解为对象主动创建依赖对象。
假设我们有一个简单的应用程序,其中包含一个 UserService 和一个UserRepository。UserService 负责处理用户相关的业务逻辑,而UserRepository负责与数据库进行交互。
public class UserService {
public void createUser(User user) { UserRepository userRepository = = new UserRepository(); userRepository.save(user); }}
public class UserRepository { public void save(User user) { // 保存用户到数据库 }}
在传统的程序设计中,UserService通常需要直接创建 UserRepository 的实例,然后使用它来完成数据库操作。这样的话,UserService 就需要直接依赖于UserRepository,导致它们之间的耦合度很高,不利于代码的维护和测试。
控制反转,IoC容器统一负责对象创建和配置的控制权,应用程序中想使用时再通过依赖注入的方式调用即可。
二、DI依赖注入
依赖注入(Dependency Injection 简称 DI) 是指在IoC容器创建对象时,先创建依赖对象,然后将依赖对象的引用注入到对象中。
在依赖注入(DI)中,依赖关系需要被明确地声明和配置,然后由应用容器(如IoC容器)负责将这些依赖关系注入到需要它们的对象中。这样,对象就不再需要直接创建它们所依赖的其他对象,而是通过IoC容器来获取这些依赖。
在 Spring 框架中,我们可以利用 IoC 容器来管理对象之间的依赖关系,实现控制反转。
具体地,我们可以通过Spring的依赖注入功能来告诉IoC容器,让它负责创建和管理 UserRepository 的实例,并将它注入到 UserService 中。
@Servicepublic class UserService {
// 使用注解进行依赖注入 @Autowiredprivate UserRepository userRepository;
public void createUser(User user) { userRepository.save(user); }}
@Repositorypublic class UserRepository { public void save(User user) { // 保存用户到数据库 }}
在应用程序启动时,我们可以配置 Spring容器,通过注解 @Service和 @Repository告诉容器如何创建 UserService 和 UserRepository 的实例。
这样一来,UserService 就不再需要直接创建 UserRepository,而是由Spring容器来负责。
在 UserService 使用 UserRepository 的时候,再通过@Autowired属性注入的方式从容器中获取实例,获取到实例后就可以直接使用了。
三、loC 控制反转实现机制
IoC 容器如何识别需要创建的对象呢?
首先声明要实例化的对象,然后 IoC 容器才能识别到要实例化的对象。
在 Spring 框架中,IoC容器通过反射机制实例化对象的过程主要涉及以下几个步骤:
1、扫描和加载类:Spring IoC容器会扫描指定的包路径,或者通过配置文件中的扫描规则来加载需要管理的类。这些类通常被标记为需要由Spring容器来管理。
2、解析和分析类的元数据:一旦类被加载,Spring容器会解析这些类的元数据,包括类的结构、字段、方法、构造函数等信息。
3、实例化对象:当需要创建一个类的实例时,Spring IoC容器会使用反射机制来实例化对象。在这个过程中,Spring会使用类的构造函数来创建对象。如果类有多个构造函数,Spring会根据配置或者注解来确定使用哪个构造函数。
4、设置对象的属性:一旦对象被实例化,Spring IoC容器会使用反射机制来设置对象的属性。这包括使用Setter方法或者直接设置字段的值。
四、DI依赖注入方式
在Spring框架中,DI通过构造函数注入、属性注入和方法注入等机制来实现。通过依赖注入,对象之间的依赖关系被解耦,使得对象更容易被替换和重用。
举两种最常用的自动注入的例子。
1、构造函数注入
@Servicepublic class UserService {
private UserRepository userRepository;
// 1、通过构造函数注入依赖 public UserService(UserRepository userRepository) { this.userRepository = userRepository; }
public void createUser(User user) { userRepository.save(user); }}
构造函数注入是通过构造函数来注入依赖项。在这种方式中,依赖项通过构造函数的参数传递给目标类。这是一种常见的依赖注入方式。
2、属性注入
在Spring框架中,除了使用XML配置文件进行依赖注入外,还可以使用注解来进行依赖注入。通过注解可以更加简洁地定义依赖关系,而无需在XML配置文件中显式指定。
@Servicepublic class UserService {
// 1、属性注入 @Autowiredprivate UserRepository userRepository;
public void createUser(User user) { userRepository.save(user); }}
在这个例子中,我们使用了@Autowired注解来标记userRepository属性,表示它需要自动注入依赖项。
使用注解来进行依赖注入可以简化配置,并且使代码更加清晰和易于理解。
@Autowired是Spring框架中最常用的注解之一,用于标记需要自动注入的依赖项。除了@Autowired外,还有其他一些注解可以用于依赖注入,例如@Resource和@Inject等。
其他依赖注入方式都需要结合xml配置文件,在这里就不演示了。
最后小结
领取专属 10元无门槛券
私享最新 技术干货