1
votes

I have defined a Bean like this in a Spring-boot Configuration(annotated with @Configuration) class :

@Bean
public MyRegistry myRegistry() {
    return new MyRegistry();
}

MyRegistry looks like this :

@Component
@Getter
@Setter
public class MyRegistry {
    Map<String, Object> resourcesMap = new HashMap<>();

    public MyRegistry() {
        resourcesMap.put("handler1", new MyHandler1());
        resourcesMap.put("handler2", new MyHandler2());
    }
}

Now, in another class with @Component, I have @Autowired myRegistry and using it as below :

MyHandler1 handler1 = new ObjectMapper().convertValue(myRegistry.getResourcesMap().get("handler1"), MyHandler1.class);

I do not get any error while starting the Spring-Boot application, but when the application running, methods of Handler1 is not accessible.

Want to understand what am I doing wrong here. I probably am messing up annotation usage as I am new to Spring-Boot

2
As you are storing Object in map than why you used: new ObjectMapper().convertValue ?Yogesh Prajapati
Direct casting would not workVHegde
Why did you invent your own MyRegistry? That's usually the job that Spring does for you.chrylis -cautiouslyoptimistic-
Could you please tell us more about your use case. You seem to create another ApplicationContext besides the one provided by Spring Boot. I've redo a similar to yours, and it worked for me BTW.RUARO Thibault

2 Answers

2
votes

So the following code (snippet1) works?

Object mHandler1Obj = myRegistry.getResourcesMap().get("handler1", MyHandler1.class);

But then it fails when you're trying to (snippet2):

MyHandler1 handler1 = new ObjectMapper().convertValue(myHandler1Obj);

If so, then spring boot is irrelevant here, the fact that "snippet1" worked already shows that spring boot has done its job.

Now its objectmapper that cannot convert a generic object to MyHandler1...

In order to reproduce it, try to "exclude" the spring boot from the equation and check solely the snippet2

This BTW can explain why did the application context (spring boot app) start without exceptions: if it can't autowire something it will fail during the starup but as you explain its not the case...

0
votes

You have already defined MyRegistry as bean using @Component, you don't need to create bean using @Configuration unless you want to create multiple beans.

I had tried below code and it's working, I hope it will be helpful.

MyRegistry.java

@Component
public class MyRegistry {

   private Map<String, Object> resource = new HashMap<>();

    public MyRegistry() {
        this.resource.put("handler", new MyHandler());
    }

    public Map<String, Object> getResource() {
        return resource;
    }
}

MyHandler.java

public class MyHandler {

    private String message;

    public MyHandler() {
        this.message = "Hello world";
    }
}

TestBean.java

@Autowired
private MyRegistry myRegistry;

@Override
public void test() throws Exception {
   MyHandler handler = new ObjectMapper().convertValue(myRegistry.getResource().get("handler"), MyHandler.class);
    System.out.printf("message "+ handler.getMessage());
}