I am very new to Micronauts and I have a fair bit of experience developing spring boot applications. With this background I was stumbled upon creating custom beans like how I used to create with @Bean
annotations on Spring applications.
In my case I have a library that provides an Interface and its implementation class. I wanted to use the interface in my code and try to inject the implementation and it failes with below error
Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [io.vpv.saml.metadata.service.MetaDataParser] exists for the given qualifier: @Named('MetaDataParserImpl'). Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
Here is my code
@Singleton
public class ParseMetadataImpl implements ParseMetadata {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Inject
@Named("MetaDataParserImpl")
private MetaDataParser metaDataParser;
@Override
public IDPMetaData getIDPMetaData(URL url) throws IOException {
logger.info("Parsing {}", url);
logger.info("metaDataParser {}", metaDataParser);
return metaDataParser.parseIDPMetaData(url);
}
}
I am sure there is somehting wrong I am doing and need to understand what to do. I have this working by adding below code and removing annotations around metaDataParser
.
@PostConstruct
public void initialize() {
//Want to Avoid This stuff
this.metaDataParser = new MetaDataParserImpl();
}
Using Spring Boot it would be possible to add a @Bean
annotation to create some custom beans we can do @Autowired
to inject it everywhere on our application. Is there an equivalent on Micronauths that I am missing. I went through the guide on https://docs.micronaut.io/2.0.0.M3/guide/index.html and was not able to get anything to get this working.
Can someone suggest how I can use the @Inject to inject custom beans?
Just incase you want to see this, here is the application on Github. https://github.com/reflexdemon/saml-metadata-viewer
With the help from Deadpool
and a bit of reading I got what I was looking for. The solution was creating @BeanFactory
See Javadoc here: https://docs.micronaut.io/latest/guide/ioc.html#builtInScopes
The
@Prototype
annotation is a synonym for@Bean
because the default scope is prototype.
Thus here is an example that will match the the behavior of Spring framework
Here is the answer for anyone who also is looking for such a thing.
import io.micronaut.context.annotation.Factory;
import io.vpv.saml.metadata.service.MetaDataParser;
import io.vpv.saml.metadata.service.MetaDataParserImpl;
import javax.inject.Singleton;
// 2024 use: import jakarta.inject.Singleton;
@Factory
public class BeanFactory {
@Singleton
public MetaDataParser getMetaDataParser() {
return new MetaDataParserImpl();
}
}