Spring 设计可替换依赖项

Spring 设计可替换依赖项

问题描述

我一直在学习Spring以重返Java(我在专业经验方面是C#,ASP.NET Core)。有一件事情有些不同,那就是Spring缺少基于接口的DI。在.NET中,例如,我可能会有一个按照如下方式排列的三层应用程序:

-API项目

-—Controllers\WeatherController.cs

-核心项目

-—IWeatherService.cs

-数据项目

-—OpenWeatherMapWeatherService.cs

在DI容器配置中,我将使用OpenWeatherMapWeatherService关联IWeatherService的依赖项。如果我以后想要使用Weather Channel,我可以添加WeatherChannelWeatherService.cs并更新IWeatherService的配置,将其指向WeatherChannelWeatherService。

是否有Spring中的一种常见方法,允许以这种方式替换依赖项?或者构造函数/设置器DI实际上不能提供这样的机制?

解决方案

  1. 与问题的三层部分相关。 您可以通过将每个层放在一个单独的包中,或将其放在一个单独的源目录中,来实施n层(3层或更多层)架构。 您可以为表示层创建一个包,并将控制器放在其中。 另一层用于业务逻辑(在该层中放置所有抽象),并将所有服务与其实现放在该层中。 数据访问层用于放置所有实体和存储库。

  2. 与可替换的接口/组件相关。 无论您在哪里工作,您都希望拥有接口和实现,以便更容易替换实现, 因此,在Spring Boot中,您可以在控制器(表示层)中使用服务接口(服务层)作为服务实现实例的类型, 并传入一个提供的实现(例如使用@Autowired注解来注入实现对象),如果有多个实现适用于具体服务,则可以使用@Qualifier注解。

考虑下面提供的代码

这个控制器使用EmployeeService接口作为服务实现对象的类型(注意,在这个例子中,框架自动注入EmployeeService实例而不使用Autowired注解,这是平台允许的另一种注入对象的方法)

RestController:

@RestController
@RequestMapping("/api")
public class EmployeeRestController {
    private EmployeeService employeeService;

    public EmployeeRestController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    @GetMapping("/employees")
    public List<Employee> findAll() {
        return employeeService.findAll();
    }
...
}

服务接口:

public interface EmployeeService {
    public List<Employee> findAll();

    public Employee findById(int theId);

...
}

服务实施:

@Service
public class EmployeeServiceImpl implements EmployeeService {
    private EmployeeDAO employeeDAO;

    @Autowired
    public EmployeeServiceImpl(EmployeeDAO employeeDAO) {
        this.employeeDAO = employeeDAO;
    }

    @Override
    @Transactional
    public List<Employee> findAll() {
        return employeeDAO.findAll();
    }
    ...
}

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程