I have two beans with the type InterfaceA.
I was trying to inject the bean into an argument of a #Bean method using #Qualifier to autowire by name.
I was surprising that Spring can't resolve the proper bean unless your parameter name is matching the bean name.
I was trying:
#Component
public class ClassA implements InterfaceA {
}
#Component
public class ClassB implements InterfaceA {
}
#Configuration
public class AppConfig {
#Bean
#Autowired
#Qualifier("classA")
public SomeOtherClass someOtherClass(InterfaceA object) {...}
}
But got the NoUniqueBeanDefinitionException.
However if I use parameter name matching the component name it works fine.
#Configuration
public class AppConfig {
#Bean
#Autowired
public SomeOtherClass someOtherClass(InterfaceA classA) {...}
}
Could someone explain why I can't use autowiring by name with #Resource or #Qualifier here?
Add the #Qualifier annotation to the parameter not to the method:
public SomeOtherClass someOtherClass(#Qualifier("classA") InterfaceA object) {...}
Related
I have an interface named IJobService
#Service
public interface IJobService {
List<SearchTupleModel> getTuplesFromJobService(List<String> jobIds);
}
I have a class JobService implementing this:
#Service
public class JobService implements IJobService {
}
In a controller, I am just autowiring this interface as:
public class JobSearchResource {
#Autowired
IJobService iJobService;
}
But I am getting the error:
No qualifying bean of type
e available:
expected at least 1 bean which qualifies as autowire candidate.
Remove #Service annotation from the Interface IJobService.
public interface JobService {
List<SearchTupleModel> getTuplesFromJobService(List<String> jobIds);
}
#Service
public class JobServiceImpl implements JobService {
}
And add #Controller to your controller
#Controller
public class JobSearchResource {
#Autowired
JobService jobService;
}
Your project Application.java(or some other name) file which is containing the main method should be in the root directory as shown in the given reference:
Application.java file should contain the annotation #SpringBootApplication which will automatically scan all the files and create beans for them if they are annotated with #Service, #Controller, #Configuration etc...
Or else if you want to keep the Application.java file in some other package then you have to explicitly mention the root directory in the component scan annotation as shown below:
#SpringBootApplication
#ComponentScan(basePackages = {"com.starterkit.springboot.brs"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Can you remove #Service above your interface IJobService ?
#Service indicates the code below is candidate for injection.
Since both IJobService and JobService have #Service, it yields 2 choices so spring does not know which one to use.
expected at least 1 bean which qualifies as autowire candidate.
This class configure a spring bean
#Configuration
public class IJobServiceConfig {
#Bean
public IJobService iJobService (){
return new IJobService ();
}
}
also Add #Controller for controller class
you should remove #Service annotation from the interface, also define your JobSearchResource bean using #Component or #Controller if its controller.
I have an interface and service implements it. It has some void methods.
I am using spring java bean configuration. But unable to create bean object because of void methods.How to handle this problem.
I tried to use #PostConstruct instead of #Bean after reading some blogs, but it didn't work out.
public interface MyInterface {
void someData(List<MyClass> list, String somedata);
}
#Service("myInterface")
public DummyClass implements MyInterface {
public void someData(List<MyClass> list, String somedata){
// my business logic
}
}
public AppConfig {
#Bean
public MyInterface myInterface {
return new DummyClass(); // but gives error void cannot return value
}
}
My Junit looks like this
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(
classes = {AppConfig.class},
loader = AnnotationConfigContextLoader.class
)
public class MyTest {
#Autowired
DummyClass dummyClass;
// If I don't use AppConfig and simply autowire then I get
"Error creating bean name, unsatisfied dependency
}
How do I achieve dependency injection here?
Use #Configuration annotation on AppConfig class, with this all the beans defined on this class will be loaded on spring context.
If you use #Service annotation on DummyClass, you do not need to declare #Bean annotation because you are already saying to spring to detect this class for dependency injection. On the other hand use #Bean annotation to specify the instantiation of the class. Normally I let the #Bean to complex classes for dependency injection or to override configurations.
I need to Autowire service interface in my controller, passing parameter logcode in not default service constructor
#Controller
public class FooController {
private Foo foo;
#Autowired
private FooService fooService //(I like passe parameter here);
}
Here's my Service:
I need to Autowire service interface in my controller, passing parameter logcode in not default service constructor
#Service
public class FooServiceImpl implements FooService {
#Autowired
private FooDAO fooDAO;
public FooServiceImpl(String pLogCode)
{
}
#Transactional
public void addFoo(Foo foo) {
fooDAO.addFoo(foo);
}
}
Passing arguments when autowiring interfaces it's only possible in XML config. Simmilar question is here:
Spring autowire interface
I have following #Configuration class
#Configuration
public class SomeClass {
#Bean
public BeanClass get() {
return new BeanClass()
}
}
Now I want to autowire BeanClass in some other class
public class SomeClass2 {
#Autowired
BeanClass beanCLass
}
Currently beanClass is coming null.
What and how exactly I need to tell spring for this autowiring.
According to Spring documentation
By default, the bean name will be that of the method name
get is your bean name, try with this configuration:
#Configurtion
public class SomeClass {
#Bean
public BeanClass beanCLass() {
return new BeanClass()
}
}
Bean
#Component
public class SomeClass2 {
#Autowired
BeanClass beanCLass
}
Your SomeClass2 must be a spring bean. Annotate SomeClass2 with #Component.
I have this Repository class which I wish to Autowire in a unit test. I'm currently getting the "no default constructor" error when running the test.
The class in question has no default constructor, I'm new to spring so may not have created the Bean correctly in the config class.
Below is the Bean in question (has no default constructor)
#Repository
public class GenericDaoImpl<T extends AbstractEntity> implements GenericDao<T> {
The config class
#Configuration
#EnableAspectJAutoProxy
#ComponentScan(basePackages = "com.example")
public class AppConfig {
#Bean
GenericDaoImpl<AbstractEntity> genericDoaIpm(final Class<AbstractEntity> tClass) {
return new GenericDaoImpl<AbstractEntity>(tClass);
}
}
And in the test I have:
#Autowired
private GenericDaoImpl<AbstractEntity> genericDaoImpl;
Is there something I'm missing or doing wrong here?
According to this and this, you only need to mark your constructor with #Autowired.
GenericDaoImpl.java
#Autowired
public GenericDaoImpl(Class<?> tClass) {
...
}
You can apply #Autowired to constructors as well. A constructor #Autowired annotation indicates that the constructor should be autowired when creating the bean, even if no elements are used while configuring the bean in XML file