关于Spring Boot学习的注入问题

依赖注入(DI)

依赖注入(Dependency Injection)是一种软件模式,旨在通过外部配置文件等方式,将对象注入并从程序的源代码中排除组件之间的依赖关系。这个模式通常用DI来缩写,取自英文的首字母。

这是一种软件模式,它从程序源代码中排除了组件间的依赖关系,并允许在运行时通过外部配置文件等方式进行注入。此处所指的组件可以替换为类。

对某物或某人有依赖或依赖性

当在类A中实例化类B时,类A不能在没有类B的情况下运行。这种状态可以说是类A和类B存在依赖关系。用代码表示如下:

public class ClassA {
    public static void main(String... args) {
        ClassB classB = new ClassB();
        System.out.println(classB.execute());
    }
}

public class ClassB {
    public execute() {
        System.out.println("ClassB::execute()");
    }
}

灌输

不是直接进行new操作,而是将设置等内容保存在外部文件中,在运行时分配指定类的实例。这个功能被称为依赖注入容器(DI容器)。

春天有这个DI容器,所以在设定好之后,它会在运行时帮我们注入实例。

Spring Boot的依赖注入(DI)

为了在Spring的DI容器中注册为bean,我们使用Spring注解。
以下注解的作用都是相同的,因此可以根据名称选择使用。

アノテーション使い所@Serviceサービス層に配置@Repositoryデータ層に配置@Controllerコントローラ層に配置@Componentその他

在将类注册到DI容器后,可以使用注入。
注入可以通过注释进行表示,以下是注入的几种方式。

アノテーションパッケージ@Autowiredorg.springframework.bean.factory@Injectjavax.inject@Resourcejavax.annotation

由于操作不变,我们将在这里使用@Autowired。
被@Autowired指定的实例将被注入。

@Autowired的用法

准备

我将创建一个用于注入的方法。由于我想要进行替换,所以我将使用接口。

left to right direction

interface ICommand {
    void execute()
}
class FirstCommand 

FirstCommand --|> ICommand
SecondCommand --|> ICommand

构造函数注入

在构造函数上添加@Autowired。
这种方法是Spring团队推荐的方法,它的优点是字段可以设置为final,并且可以在构造函数中指定其他实例。

@Slf4j
@Service
public class ConstructorAutowiredService {

    private final IComponent component;

    @Autowired
    public ConstructorAutowiredService(IComponent secondComponent) {
        this.component = secondComponent;
    }

    @PostConstruct
    public void execute() {
        log.info("execute()");
        this.component.execute();
    }
}

通过将构造函数的参数名(在这里是secondComponent)设置为类名的小驼峰命名法,自动注入SecondComponent。
将这里设置为firstComponent,注入FirstComponent。

为了使ConstructorAutowiredService.java更容易理解,我们创建了一个构造函数并在其上添加了@Autowired。但为了更简洁地编写代码,我们将使用带有final字段的构造函数参数的注解@RequiredArgsConstructor。

@Slf4j
@RequiredArgsConstructor
@Service
public class RequiredArgsConstructorService {

    // @RequiredArgsConstructorを使った場合は@Autowiredは省略できる
    private final IComponent firstComponent;

    // もちろんConstructorも省略できる

    @PostConstruct
    public void execute() {
        log.info("execute()");
        this.firstComponent.execute();
    }
}

用这种写法,可以省略@Autowired和构造函数。

注入攻击

在字段上加上@Autowired注释是一种简洁明了的方法。

@Slf4j
@Service
public class FirstComponentService {

    @Autowired
    private IComponent firstComponent;

    @PostConstruct
    public void execute() {
        log.info("execute()");
        this.firstComponent.execute();
    }

}
@Slf4j
@Service
public class SecondComponentService {

    @Autowired
    private IComponent secondComponent;

    @PostConstruct
    public void execute() {
        log.info("execute()");
        this.secondComponent.execute();
    }

}

在注入类的定位方面,与构造函数注入类似,依靠的是类的名称。

引擎注入

如其名,@Autowired用于Setter。
由于找不到合适的使用场景,所以没有示例。

使用配置进行设置。

我们已经看到了基本的方法,但是尽管称之为依赖注入,但字段名称与类名称相关联并且不方便使用。
因此,我们将提供一种通过指定名称来注入实例的方法。

Configuration用于定义Bean。换句话说,它设置了在DI容器中使用哪个实例以及初始值的注入方式。
Configuration可以通过以下方式进行设置:
– 配置文件(xml)
– 类
– 注解

这个是可设定的,但是在这里我们会用注释完成。

创建@Configuration类

在Configuration类上添加@Configuration注解。
在方法上添加@Bean注解。可以带参数以便进行区分。
尽管这里只是简单地执行了new操作,但从写法可以看出,在此可以对实例进行值的设置。

@Configuration
public class App {

    @Bean("component1")
    public IComponent getComponent1() {
        return new FirstComponent();
    }

    @Bean("component2")
    public IComponent getComponent2() {
        return new SecondComponent();
    }
}

使用配置

我将使用Configuration中设置的Bean进行注入。在这个例子中,我将演示构造函数注入。

@Slf4j
@Service
public class UsinAppConfigService {

    private final IComponent component;

    @Autowired
    public UsinAppConfigService(@Qualifier("component1") IComponent component) {
        this.component = component;
    }

    @PostConstruct
    public void execute() {
        log.info("service executed");
        this.component.execute();
    }
}

要指定名字获取Bean,需要使用@Qualifier注解。
@Qualifier与@Autowired一起使用。
在构造函数的参数中使用@Qualifier指定名字。
执行时,将执行FirstComponent。

总结

由于可以将其作为存根进行单元测试,因此它看起来对开发非常有用。
例如,RestTemplate在URL中查询JSON并返回,但是我们是否可以注入并返回固定的JSON呢?

在商业领域中,策略模式是开发必需且有用的功能。我们希望能够利用现有的DI容器,提高开发速度。

请提供参考资料。

关于依存性注入(DI):
关于@Component、@Service、@Repository、@Controller的区别:
关于@Autowired、@Inject、@Resource的区别的验证

广告
将在 10 秒后关闭
bannerAds