Spring: two beans qualified different with the same name - spring

Two beans qualidied different with the same name are getting me an exception.
Exception message:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'tipusFonsSql', defined in class path resource [net/gencat/clt/arxius/connector/config/SqlGiacTxtResourceLoader.class], could not be registered. A bean with that name has already been defined in class path resource [net/gencat/clt/arxius/connector/config/SqlGiacImgResourceLoader.class] and overriding is disabled.
It's telling me that class SqlGiacTxtResourceLoader and class SqlGiacImgResourceLoader are defining two beans with a same name.
Nevertheless, they are "#Qualified" different. I mean:
Into SqlGiacImgResourceLoader
#Bean
#GiacImg #TipusFonsQ
public String tipusFonsSql() {
//...
}
Into SqlGiacTxtResourceLoader
#Bean
#GiacTxt #TipusFonsQ
public String tipusFonsSql() {
//...
}
As you can see, one is "#aulified" with #GiacImg annotation and the other ony by #GiacTxt.
Any ideas?

You have to name them like this
#Bean(name = "GiacImg TipusFonsQ")
public String tipusFonsSql() {
//...
}
and
#Bean(name = "GiacTxt TipusFonsQ")
public String tipusFonsSql() {
//...
}
to avoid bean conflict

There is 2 way to resolve this issue ( haha there could be many but I know below 2 approach):------
1st Method
change the bean name:---
#Bean(name = "custome bean name")
2nd Method
write down the below key in the application.properties:--
spring.main.allow-bean-definition-overriding=true
NOTE:-in your case you can change method name also

Related

spring boot component with string parameters

i have a component that reads a configuration value from application.properties and accepts a string parameter in its constructor as such..
#Component
public class Person
{
#Value("${greeting}")
String greeting;
String name;
public Person(String name)
{
this.name = name;
onGreet( greeting + ", " + name );
}
public void onGreet(String message)
{
}
}
I need to instantiate this component as follows and override its "onGreet" event in the calling code as follows:
Person jack = new Person("jack")
{
public void onGreet(String message)
{
System.out.println( message );
}
};
However I end up getting this..
Parameter 0 of constructor in demo11.Person required a bean of type 'java.lang.String' that could not be found.
My application.properties is as follows:
greeting=hello
What am I missing here? Thank you.
It is literally telling you that the only constructor that you have requires a parameter that Spring knows nothing about.
Add a #Value to that String name in the constructor (right before the parameter) like so public Person(#Value("${name}") String name) if you want Spring to initalize it or remove that constructor
EDIT: some more explanation:
Spring is a dependency injection container. Meaning you define beans and let Spring create and inject them for you. Defining beans can be done in several ways (Java configuration, annotations or xml) here you are using annotation way via #Component.
Now that you have defined your bean (aka component) for Spring it will create it. For it to create it it needs to call a constructor. For that you need to provide it with all information necessary for constructor call - meaning all parameters. If parameters are other classes they need to be defined as beans as well (For example via #Component) if they are simple types like String you need to provide #Value for them.
Lastly if you ever use new ... to define Spring managed beans then the whole Spring magic disappears since Spring doesnt know about this bean instantiation anymore and will not autowire anything into it. For all intenses and purposes Spring is not aware of any objects you create with new.

StateMachineRuntimePersister Instantiation getting failed because Spring not able to find its dependent bean MongoDbStateMachineRepository

I am new to spring state machines. I am trying to setup state machine for my transaction data and externalise it to mongo database. But i am getting error while creating "StateMachineRuntimePersister" bean.
Error says - Parameter 0 of method mongoPersist in com.pws.funder.config.PersistConfig required a bean of type 'org.springframework.statemachine.data.mongodb.MongoDbStateMachineRepository' that could not be found
#Configuration
public class PersistConfig {
#Bean(name="runtime")
public StateMachineRuntimePersister<WalletGatewayStates, WalletGatewayEvents, UUID> mongoPersist(
MongoDbStateMachineRepository mongoRepository) {
return new MongoDbPersistingStateMachineInterceptor<WalletGatewayStates,WalletGatewayEvents,UUID>(mongoRepository);
}
}
Any leads would be helpful.
Just create interface like this:
public interface StateMachineRepository extends MongoDbStateMachineRepository {
}
and pass it into mongoPersist method.
Spring automatically creates implementation from your repository interface and put this bean in the context.

Evaluate property from properties file in Spring's #EventListener(condition = "...")

I would like to make the execution of an event handler dependent on whether or not a property is set to true in a properties file.
#EventListener(ContextRefreshedEvent.class, condition = "${service.enabled}")
public void onStartup() { }
However, this does not seem to work. I am getting the following error on startup:
org.springframework.expression.spel.SpelParseException: EL1043E:(pos 1): Unexpected token. Expected 'identifier' but was 'lcurly({)'
Is it possible to use a property from a properties file as a condition here?
The issue is condition argument is expecting a SPEL.
This works try it out.
In your bean where you have this #EventListener, add these lines
public boolean isServiceEnabled() {
return serviceEnabled;
}
#Value("${service.enabled}")
public boolean serviceEnabled;
change your declaration of evnt listener like this
#EventListener(classes = ContextRefreshedEvent.class, condition = "#yourbeanname.isServiceEnabled()")
public void onStartup() { }
change yourbeanname with the correct bean name .
I had the same annoying experience (with Spring Boot 2.4.2 on Java11).
In my case I had the boolean property in a #ConfigurationProperties class anyways in the same java file and still struggled a bit. First the #ConfigurationProperties need to be annotated as #Component to actually be a valid Bean and can be used in SpEL.
And I had to use the same long attributeName for the ConfigurationProperties in the Service itself and the EventListener Annotation for the Bean resolution to work fine. I needed some the ConfigurationProperties values also in another place of the Service, that's why they needed to be (Constructor) Autowired as well...
So this worked for me:
#ConfigurationProperties("my.custom.path")
#Component //Important to make this a proper Spring Bean
#Data //Lombok magic for getters/setters etc.
class MyCustomConfigurationProperties {
boolean refreshAfterStartup = true;
}
#Service
#RequiredArgsConstructor //Lombok for the constructor
#EnableConfigurationProperties(MyCustomConfigurationProperties.class)
#EnableScheduling
public class MyCustomService {
private final MyCustomConfigurationProperties myCustomConfigurationProperties;
#EventListener(value = ApplicationReadyEvent.class, condition = "#myCustomConfigurationProperties.refreshAfterStartup")
public void refresh() {
//the actual code I want to execute on startup conditionally
}
}

Autowire list of beans of a type in Grails

I am trying to autowire a list of beans of a given type into my Bootstrap.groovy.
Say, I have the below interface and classes.
interface Vehicle {
}
#Component
class Car implements Vehicle {
boolean byName = false
}
#Component
class Van implements Vehicle {
boolean byName = false
}
And my Bootstrap.groovy looks like this:
class Bootstrap {
List<Vehicle> vehicles
def init = { servletContext ->
println "Vehicles are ${vehicles}" // prints null
}
}
I am sure I have set up component scanning correctly as I can see normal beans being wired up. However, it looks like autowiring by type isn't happening, causing the Spring container to try to wire the list of Vehicles by name and failing in the process.
Any insights would be appreciated.
I am using Grails 2.4.3

Overzealous auto-wiring of spring bean properties in grails

I have a domain class:
class Searcher {
String names
List<String> getExperiments() {
return names.split(',');
}
void setExperiments(List<String> list) {
names = list.join(',');
}
}
and a bean defined in the resource file
experiments(com.fxpal.querium.experiment.ExperimentHolder) {
otherProp = 'foo'
}
The experiments bean is semantically different from the experiments property of the Searcher class.
How do I prevent Spring from auto-wiring a specific property of a specific bean? Since the experiments property of the Searcher bean is derived, I don't want Spring to touch it at all.
Why not just name your bean experimentHolder? By default its going to auto wire by name.

Resources