Spring中的依赖注入(DI,Dependency Injection)是Spring框架的核心功能之一,它通过将对象的依赖关系交由Spring容器来管理,从而实现了类与类之间的解耦。通过依赖注入,开发者无需自己创建和管理依赖对象,Spring容器会自动将它们注入到相应的Bean中。
依赖注入的基本思想是将类所依赖的对象的创建、管理交给Spring容器,而不是由类本身来创建。这种方式使得类之间的耦合度降低,代码更加灵活、可维护,并且容易进行单元测试。
Spring支持三种常见的依赖注入方式:
构造器注入是通过构造方法来注入依赖对象。在创建Bean的时候,Spring容器会通过构造器将所需的依赖注入到Bean中。这种方式的优点是依赖关系是不可变的,即一旦创建Bean,依赖关系就已经确定。
@Component
public class Car {
private Engine engine;
// 构造器注入
@Autowired
public Car(Engine engine) {
this.engine = engine;
}
public void start() {
engine.run();
}
}
@Component
public class Engine {
public void run() {
System.out.println("Engine running...");
}
}
在这个例子中,Car
类依赖于Engine
类。在构造器中,我们使用@Autowired
注解标注构造器,告诉Spring容器在实例化Car
时需要注入Engine
实例。
Setter注入是通过JavaBean的Setter方法来注入依赖对象。在Bean实例化后,Spring容器会调用Setter方法将所需的依赖注入进去。Setter注入适用于那些依赖关系是可选的或者可变的场景。
@Component
public class Car {
private Engine engine;
// Setter方法注入
@Autowired
public void setEngine(Engine engine) {
this.engine = engine;
}
public void start() {
engine.run();
}
}
@Component
public class Engine {
public void run() {
System.out.println("Engine running...");
}
}
在这个例子中,Car
类通过setEngine
方法注入Engine
实例。@Autowired
注解标注在Setter方法上,表示该方法的参数需要由Spring容器自动注入。
字段注入是通过直接注入到字段来实现依赖注入。这是Spring提供的一种最简洁的注入方式,通过在字段上使用@Autowired
注解,Spring容器会自动将所需的依赖注入到该字段中。
@Component
public class Car {
@Autowired
private Engine engine;
public void start() {
engine.run();
}
}
@Component
public class Engine {
public void run() {
System.out.println("Engine running...");
}
}
在这个例子中,Engine
实例通过@Autowired
注解直接注入到Car
类的engine
字段中。
Spring容器使用@Autowired
注解来自动装配依赖。当我们使用@Autowired
注解时,Spring会根据类型自动查找与字段、构造器或Setter方法匹配的Bean。默认情况下,Spring会自动根据Bean的类型进行装配。
按类型自动装配(默认方式):根据Bean的类型自动匹配。
@Autowired
private Engine engine;
按名称自动装配:Spring会根据Bean的名称来进行自动装配。如果Bean的名称与属性名匹配,就会注入对应的Bean。可以通过@Qualifier
注解来指定具体的Bean。
@Autowired
@Qualifier("engine1") // 根据Bean名称指定装配哪个Engine实例
private Engine engine;
按构造器自动装配:Spring会根据构造器的参数类型来自动装配依赖。
@Autowired
public Car(Engine engine) {
this.engine = engine;
}
当容器中有多个候选Bean时,@Qualifier
注解可以用来指定注入哪个Bean。通常与@Autowired
一起使用,@Qualifier
用于指定Bean的名称。
@Component
@Qualifier("engine1")
public class Engine1 implements Engine {
// Engine1的实现
}
@Component
@Qualifier("engine2")
public class Engine2 implements Engine {
// Engine2的实现
}
@Component
public class Car {
@Autowired
@Qualifier("engine1") // 明确指定注入Engine1
private Engine engine;
}
当存在多个候选Bean时,可以使用@Primary
注解指定一个默认的Bean,这样在注入时,Spring容器会优先选择标记为@Primary
的Bean。
@Component
@Primary
public class Engine1 implements Engine {
// Engine1的实现
}
@Component
public class Engine2 implements Engine {
// Engine2的实现
}
@Component
public class Car {
@Autowired
private Engine engine; // 默认注入Engine1,因为它被标记为@Primary
}
Spring的依赖注入(DI)是通过将Bean的依赖关系交给容器管理,减少了代码的耦合度,提高了代码的灵活性和可测试性。常用的依赖注入方式包括: