如何在其构造函数中获取使用依赖注入的类的实例

Posted

技术标签:

【中文标题】如何在其构造函数中获取使用依赖注入的类的实例【英文标题】:How to get instance of class that uses dependency injection in its constructor 【发布时间】:2020-12-30 13:05:32 【问题描述】:

好的,所以标题可能不是最好的,但我在这里。所以我的 Vaadin 应用程序是一页,没有其他路线。虽然 Web 应用程序是一页,但我选择根据布局等将页面拆分为不同的类。有一个名为 MainLayout.class 的主类,它有 @Route("")。

这里是网站的大致轮廓,每个轮廓代表一个新的类,它延长了组件的一些时间。 (为了保持简洁,下半部分缺失。)

现在的问题是红色和蓝色组件都使用依赖注入来注入所需的服务。这一切都很好,但是当 purple 布局想要同时保存 Red 和 Blue 类的实例以便它可以将组件添加到自身时,问题就出现了。

我目前的做法: 我目前感觉非常hacky和错误的方法只是通过将蓝色和红色组件类注入紫色类的构造函数来再次使用依赖注入。这个过程一直持续到它到达 MainLayout 类。

我的问题: 是否有任何其他可能的解决方案来解决这个问题?如果有,我可以如何或在哪里解决这个问题?

主布局类:(它使用依赖注入来获取所有其他也包含子组件等的子布局)

@Route("")
@PageTitle("Ur Weather App")
@CssImport("./styles/shared-styles.css")
@PreserveOnRefresh
public class MainLayout extends VerticalLayout 
    private static final long serialVersionUID = 1L;

    private final NavigationView searchBar;
    private final CurrentInfoLayout currentInfoLayout;
    private final MoreDetailInfoLayout moreDetailInfoLayout;

    @Autowired
    public MainLayout(NavigationView searchBar,
                        CurrentInfoLayout currentInfoLayout,
                        MoreDetailInfoLayout moreDetailInfoLayout) 
        this.searchBar = searchBar;
        this.currentInfoLayout = currentInfoLayout;
        this.moreDetailInfoLayout = moreDetailInfoLayout;
        addClassName("main-layout");

        add(this.searchBar, this.currentInfoLayout, this.moreDetailInfoLayout);
    


红色组件:(蓝色组件在某种程度上相似)

@Component
@UIScope
@CssImport("./styles/current-info-styles.css")
public class CurrentDayView extends VerticalLayout 
    private static final long serialVersionUID = 1L;

    private NowcastWeatherService nowcastWeatherService;
    private GeoLocationService geoLocationService;

    //Some other code here

    @Autowired
    public CurrentDayView(NowcastWeatherService nowcastWeatherService, GeoLocationService geoLocationService) 
        this.nowcastWeatherService = nowcastWeatherService;
        this.geoLocationService = geoLocationService;

        //Other functionality here
    
    //Other code here

紫色组件:(这是使用依赖注入来获取其他组件。)

@Component
@UIScope
@CssImport("./styles/current-info-styles.css")
public class CurrentInfoLayout extends HorizontalLayout 

    private CurrentDayView currentDayView;
    private CurrentTemperatureView currentTemperatureView;

    @Autowired
    public CurrentInfoLayout(CurrentDayView currentDayView, CurrentTemperatureView currentTemperatureView) 
        this.currentDayView = currentDayView;
        this.currentTemperatureView = currentTemperatureView;
        this.searchBar = searchBar;

        //Other functionality here
    
    //Other code here

正如您可能知道的那样,我对大部分这些东西都相当了解,所以我可能不知道依赖注入等的最佳策略。 感谢您的宝贵时间!

【问题讨论】:

有什么问题?请添加您获得的错误/堆栈跟踪,或者它的行为方式与您想象的不同。 【参考方案1】:

从 spring 和依赖注入的角度来看(我没有使用 Vaadin),你做得对。您正在通过构造函数注入,这是推荐的方式。您可以做的更多是将final 关键字添加到您在MainLayout 中所做的注入属性中。

如果您想避免使用依赖注入,可以在实例化父组件时使用Singleton 模式来检索所需组件的实例。

【讨论】:

嗯好的。因此,假设我有一个使用服务并通过依赖注入获取它的组件。其他任何想要该类的实例、使用服务的人都必须使用依赖注入。这个循环将重复,直到它达到“***”类。这不会导致紧密耦合和高度依赖的类吗?它们不应该是“松散”耦合而不是直接耦合吗? 实际上依赖注入有助于获得松散耦合的类,尤其是当您使用接口而不是服务的实际实现时。

以上是关于如何在其构造函数中获取使用依赖注入的类的实例的主要内容,如果未能解决你的问题,请参考以下文章

laravel中的构造函数依赖注入理解

依赖注入方法

运用Unity实现依赖注入[结合简单三层实例]

在 Startup 类中获取依赖于 DI 的类的实例

如何使用手动依赖注入实例化一个类?

当有多个实现接口的类时,如何指定构造函数注入[重复]