Suppose I have a component such as:
@Component
public class MyComponent {
...
}
Now, I want to instantiate this component manually and make it a singleton, so in my main function, I create a new context and then create a new MyComponent and register it as a singleton:
var context = new AnnotationConfigApplicationContext(AppConfig.class);
context.getBeanFactory().registerSingleton(MyComponent.class.getCanonicalName() + ".ORIGINAL", new MyComponent());
context.refresh();
The problem I am finding is that MyComponent is still being created by Spring, so I don't end up with a single instance of the class, but two.
How can I make this work?
Full example:
Main class:
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 {
}
MyComponent.java
package my.spring;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
public final String myName = getClass().getCanonicalName();
}
The solution I am looking for should not involve filtering out MyComponent in the AppConfig component scan. I am looking for a dynamic solution that will allow me to tell spring not to create certain singletons when they already exist in the dependency graph.
Is this possible or not?