Reputation: 97
I am working on an application which uses some third java libraries which are build on top of core spring framework. Now when my application uses these libraries I am getting ConflictingBeanDefinitionException because two libraries have the same bean name. Now as these libraries are external I cannot change the bean name. Is there a way by which in my application I can use both the beans in same container?
@Component
class ApplicationLogic {
@Autowire FetcherAndResolver fetchFromLibraryA;
@Autowire FetcherAndResolver fetchFromLibraryB; //Because both bean names are same here comes the exception.
}
Upvotes: 1
Views: 2655
Reputation: 319
First component from third java libraries:
package com.example.component1;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
public String makeSomeWork() {
return "Component 1";
}
}
Second component from third java libraries:
package com.example.component2;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
public String makeSomeWork() {
return "Component 2";
}
}
Controller:
package com.example.controller;
import com.example.component1.MyComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Autowired
private MyComponent myComponent;
@Autowired
private com.example.component2.MyComponent myComponent2;
@RequestMapping("/components")
public String getComponents() {
return myComponent.makeSomeWork() + "_" + myComponent2.makeSomeWork();
}
}
Upvotes: 1
Reputation: 3749
I think this would require a bit of a hack.
First of all, structure your packages in a way so that external beans are not added automatically.
So, if external class is located in package a.b
. Then you have to move your own classes in either a.c
or a.b.c
. THis will ensure that you are in control of how beans are initialized.
Once this is done, you can add a @Configuration
class where you can create Beans of both type:
@Configuration
public class ExternalBeanConfiguration {
@Bean("internal-resolver" )
public FetcherAndResolver internalResolver() {
return new FetcherAndResolver();
}
@Bean("external-resolver" )
public a.b.c.FetcherAndResolver externalResolver() {
return new a.b.c.FetcherAndResolver();
}
}
I am assuming that FetcherAndResolver
is a class rather than an interface. If it is an interface, it is easier to do it as you won't have to use fully-qualified name for classes.
Then you can simply autowire with qualifiers.
@Component
public class SomeComponent {
@Qualifier( "internal-resolver" )
FetcherAndResolver internalResolver;
@Qualifier( "external-resolver" )
FetcherAndResolver externalResolver;
}
Upvotes: 1