gpt4 book ai didi

java - Spring手动创建组件并注册为单例

转载 作者:行者123 更新时间:2023-12-05 05:08:29 25 4
gpt4 key购买 nike

假设我有一个组件,例如:

@Component
public class MyComponent {
...
}

现在,我想手动实例化这个组件并使其成为单例,所以在我的主要函数中,我创建了一个新的上下文,然后创建了一个新的 MyComponent 并将其注册为单例:

var context = new AnnotationConfigApplicationContext(AppConfig.class);
context.getBeanFactory().registerSingleton(MyComponent.class.getCanonicalName() + ".ORIGINAL", new MyComponent());
context.refresh();

我发现的问题是 MyComponent 仍在由 Spring 创建,所以我最终得到的不是该类的一个实例,而是两个。

我怎样才能让它工作?

完整示例:

主类:

package my.spring;

import static org.springframework.beans.factory.config.AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTest extends Application {

@Override
public void start(Stage primaryStage) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
context.getBeanFactory()
.registerSingleton(MyComponent.class.getCanonicalName() + ORIGINAL_INSTANCE_SUFFIX,
new MyComponent());

MyComponent singleton = context.getBean(MyComponent.class); // This fails because there are now two such types

primaryStage.setScene(new Scene(new VBox(20,
new TextArea("Hello Spring"),
new TextArea(singleton.myName))));
primaryStage.setOnCloseRequest(w -> context.close());
primaryStage.show();
}
}

AppConfig.java

package my.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class AppConfig {

}

我的组件.java

package my.spring;

import org.springframework.stereotype.Component;

@Component
public class MyComponent {
public final String myName = getClass().getCanonicalName();
}

我正在寻找的解决方案不应涉及在AppConfig 组件扫描中过滤MyComponent。我正在寻找一个动态解决方案,它可以让我告诉 spring 不要创建某些单例,当它们已经存在于依赖关系图中时。

这可能吗?

最佳答案

这里有不同的解决方案:

1) 从您的类 ``MyComponent` 中删除注释 @Component

2) 定义接口(interface),将其作为接口(interface)注入(inject)到你需要的地方。在您的代码中创建和实现接口(interface),例如“... registerSingleton(..., new MyComponentImpl())”。

以下方法不能满足您的所有要求,但我建议您也考虑一下。

3) 如果您的目标只是注册一个具有特定名称的组件,请考虑使用@Component("MyName")

4) 使用配置类(用@Configuration注解)。在提供 MyComponent 类型 bean 的方法中手动创建您的 bean。在这里您没有手动注册 bean,但您仍然可以控制 bean 的创建。例如,您可以根据某些配置参数对其进行不同的初始化,或者您甚至可以创建不同子类的实例。

5) 实现将创建此 bean 的工厂。同样,您不会直接注入(inject)它。但是您将完全控制 bean 的创建。

如果您告诉我们您实际想要实现的目标,还可以有其他解决方案。

关于java - Spring手动创建组件并注册为单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58243489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com