依赖注入的方式有几种,各是什么?

构造器注入

构造器注入是通过类的构造器来传递依赖对象。当创建一个类的实例时,所有必需的依赖都通过构造器传递进来。
优点: 对象初始化完成后便可获得可使用的对象。
缺点: 当需要注入的对象很多时,构造器参数列表将会很长; 不够灵活。

@Component
public class CarService {
    private Engine engine;

    @Autowired
    public CarService(Engine engine) {
        this.engine = engine;  // 依赖通过构造器注入
    }

    public void start() {
        engine.start();
    }
}

@Component
public class Engine {
    public void start() {
        System.out.println("Engine started.");
    }
}

@Configuration
@ComponentScan(basePackages = "com.example")  // 替换为实际包名
public class AppConfig {
}

public class Main {
    public static void main(String[] args) {
        // 创建并配置Spring应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // 获取CarService bean
        CarService carService = context.getBean(CarService.class);

        // 使用CarService
        carService.start();

        // 关闭上下文
        context.close();
    }
}

设置器注入(setter方法注入)

设置器注入通过类的公开设置方法(setter)来注入依赖。这允许在对象创建之后的任何时候设置依赖。
优点: 灵活。可以选择性地注入需要的对象。
缺点: 依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用。

@Component
public class CarService {
    private Engine engine;

    @Autowired
    public void setEngine(Engine engine) {
        this.engine = engine;  // 依赖通过设置器方法注入
    }

    public void start() {
        engine.start();
    }
}

@Component
public class Engine {
    public void start() {
        System.out.println("Engine started.");
    }
}

@Configuration
@ComponentScan(basePackages = "com.example")  // 替换为实际包名
public class AppConfig {
}

public class Main {
    public static void main(String[] args) {
        // 创建并配置Spring应用上下文
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // 获取CarService bean
        CarService carService = context.getBean(CarService.class);

        // 使用CarService
        carService.start();

        // 关闭上下文
        context.close();
    }
}

在这个例子中,CarService 使用一个设置器方法 setEngine 来接收 Engine 的依赖。Spring容器负责调用这个方法,并传入一个 Engine 实例。

构造器注入: 依赖对象在Bean实例化阶段通过构造器传递。
Setter方法注入: 依赖对象在Bean实例化之后,通过调用Setter方法注入。

自动执行的过程
Spring上下文初始化:

  • 当Spring应用启动时,Spring容器会扫描配置中指定的包,寻找使用了@Component、@Service、@Repository、@Controller等注解标记的类,并将这些类实例化为Bean。

依赖注入:

  • Spring容器在实例化Bean时,会查找Bean中使用@Autowired注解的字段、构造方法或setter方法。
  • 对于使用@Autowired注解的setter方法,Spring容器会调用该方法,并自动注入需要的依赖。

执行setter方法:

  • 当Spring容器创建并初始化Bean时,如果发现setter方法上有@Autowired注解,就会自动调用这个方法并传入相应的依赖。

字段注入(Field Injection)

字段注入是通过在类的字段上直接使用注解(如@Autowired)来注入依赖。这是最简单直接的一种方式。
优点:

  • 编码简便:不需要编写构造器或设置器,只需在字段上添加注解即可完成注入,简化了代码。
  • 快速开发:特别适合快速开发和原型设计,可以快速搭建应用。

缺点:

  • 难以测试:字段注入使得在没有Spring容器的环境中进行单元测试变得更加困难,因为没有简单的方法来设置这些依赖。
  • 过度依赖框架:使得代码与Spring框架高度耦合,并且依赖关系不显式,降低了代码的可移植性和可读性。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;  // 直接在字段上注入依赖

    public void performAction() {
        userRepository.action();
    }
}

@Component
public class UserRepository {
    public void action() {
        System.out.println("Performing user repository action");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值