Search code examples
springdependency-injectionjavabeansspring-bean

Null pointer while trying to access Bean


I have a configuration class which creates multiple beans:

@Configuration
public class TopLevelConfig {
    @Bean
    public MyMapper myMapper() {
        MyMapper mapper = new MyMapper();
        mapper.registerModule(new MetadataModule());
        return new MyMapper();
    }
}

Now in MetadataModule:

@Override
public void setupModule(final SetupContext setupContext) {
    final SimpleDeserializers deserializers = new SimpleDeserializers();

    deserializers.addDeserializer(Payload.class, new PayloadDeserializer());
    setupContext.addDeserializers(deserializers);
}

In PayloadDeserializer I'm not able to autowire the MyMapper class. I'm thinking this is because when the new Object of PayloadDeserializer is created, the bean of MyMapper hasn't been created by then. How do I allow PayloadDeserializer to get access to the bean object?


Solution

  • You are creating PayloadDeserializer object by yourself by calling new PayloadDeserializer(), this is the reason why MyMapper is not injected to it. To inject/autowire to work, your bean should be spring managed. To do that, you can use @Component on top of your PayloadDeserializer class like below.

    @Component
    public class PayloadDeserializer {
        private final MyMapper mapper;
    
        @Autowired
        public PayloadDeserializer(MyMapper mapper) {
            this.mapper = mapper;
        }
    }
    
    @Configuration
    public class TopLevelConfig {
        @Bean
        public MyMapper myMapper(PayloadDeserializer payloadDeserializer) {
            MyMapper mapper = new MyMapper();
            mapper.registerModule(metadataModule(payloadDeserializer));
            return mapper;
        }
    
        @Bean
        public MetadataModule metadataModule(PayloadDeserializer payloadDeserializer) {
            return new MetadataModule(payloadDeserializer);
        }
    }
    
    public class MetadataModule {
        private final PayloadDeserializer payloadDeserializer;
        public MetadataModule(PayloadDeserializer payloadDeserializer) {
            this.payloadDeserializer = payloadDeserializer;
        }
    
        @Override
        public void setupModule(final SetupContext setupContext) {
            final SimpleDeserializers deserializers = new SimpleDeserializers();
    
            deserializers.addDeserializer(Payload.class, payloadDeserializer);
            setupContext.addDeserializers(deserializers);
        }
    }