Problem with Autowiring & No unique bean - spring

I have 2 classes (B,C) extends class A.
#Service
public class A extends AbstratClass<Modele>{
#Autowired
A(MyClass br) {
super(br);
}
#Service
public class B extends A{
#Autowired
B (MyClass br) {
super(br);
}
#Service
public class C extends A{
#Autowired
C (MyClass br) {
super(br);
}
But i have this message:
No unique bean of type [A] ] is defined: expected single matching bean but found 2: [A, B, moveModeleMarshaller]
I really cant get why i have this message & how to resolve even after reading Spring documentation.
Thanks in advance.

You should rewrite your class to something like this with the #Qualifier annotation.
#Service
#Qualifier("a")
public class A extends AbstratClass<Modele>{
#Autowired
A(MyClass br) {
super(br);
}
#Service
#Qualifier("b")
public class B extends A{
#Autowired
B (MyClass br) {
super(br);
}
#Service
#Qualifier("c")
public class C extends A{
#Autowired
C (MyClass br) {
super(br);
}
You must also use the #Qualifier annotation on the instance of type A you're autowiring the Spring bean into.
Something like this:
public class Demo {
#Autowired
#Qualifier("a")
private A a;
#Autowired
#Qualifier("b")
private A a2;
public void demo(..) {..}
}
If you don't like to have this Spring configuration in your production code, you have to write the dependency injection logic with XML or Java configuration instead.
You can also specify a default bean of type A with the #Primary annotation above one of your service classes that extends type A. Then Spring can autowire without specifying the #Qualifier annotation.
Since Spring will never try to guess which bean to inject, you have to specify which one or mark one of them with #Primary as long as its more than one bean of a type.

You are trying (somewhere else) to autowire a bean of type A. Something like:
#Autowired
private A beanA;
But you have 2 beans that conform to this.
You can resolve this by using #Resource and specifying which bean exactly:
#Resource("b")
private A beanA;
(where "b" is the name of the injected bean) or using the #Qualifier annotation.

Generally you will get this error when defined two beans with same class
<bean id="a" class="com.package.MyClass"/>
<bean id="b" class="com.package.MyClass"/>
if you address the above two line we have two beans with same class.
when you trying to autowire this class in any other classed you will get this type of error
You have two solutions
First Method
use qualifier by defining a bean id init
like this
#Autowired
#Qualifier("a")
MyClass a;
#Autowired
#Qualifier("b")
MyClass b;
Second Method
use JSR250 api(its a jar file you can put into your class path
Then do autowriring like below
#Resource("a")
MyClass a
#Resource("b")
MyClass a

Related

#AutoWired without #Qualifier

If there are two beans of the same type but with different names. Will spring Autowire the bean based on the name without us adding #Qualifier on the variable? I saw in the documentation, "As a fallback Spring uses the bean name as a default qualifier value".
#Component
class A{
}
#Component
class B extends A{
}
class C{
#AutoWired
A a;
//Will a be of type class A, even without #Qualifier...?
}
If there are two beans of the same type but with different names. Will spring Autowire the bean based on the name without us adding #Qualifier on the variable?
#Autowire in the first place cares about type, later about the name. You will get exception saying that there are multiple candidates for injection while only 1 is expected.
#Resource on the other hand, cares about name first, type later.
In this case, B will get injected because there is an A and a B for Spring to choose from and only one of them matches what the #Autowired field is asking for (Class B, because A is not assignable to B).
However, if you had two B's, you would have to qualify it or mark one of them as the primary.
For example, given this:
#Configuration
public class MyConfig {
#Bean
public B example1() {
return new B();
}
#Bean
public B example2() {
return new B();
}
}
Well, now you have two instances of B, with different names. You can fix this one of two ways:
Qualify your Autowire
Note that I'm using field injection here, you really should use constructor, I'm doing it to save space.
#Component
public class SomeComponent {
#Autowired
#Qualifier("example1")
private B b;
}
Or
Mark A Bean as Primary
Redefine the beans, marking one as #Primary
#Configuration
public class MyConfig {
#Bean
#Primary // <-------- NEW!
public B example1() {
return new B();
}
#Bean
public B example2() {
return new B();
}
}
And then inject without needing to name it:
#Component
public class SomeComponent {
#Autowired // (Will pick Primary)
private B b;
}

CDI - #Any and #Inject

Trying to inject bean in a class which has field with #Any annotation. But getting error as -
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.enterprise.inject.Instance' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#javax.inject.Inject(), #javax.enterprise.inject.Any()}
#Named
#Singleton
public class ProcessorFactoryImpl implements ProcessorFactory {
#Inject #Any
private Instance<Processor> processorList;
}
Interface is
public interface Processor {
some method
}
And implementing class is :
#Named
#Singleton
#Default
public class ProcessorImpl implements Processor {
}
For now, I have only one implementation so did not create qualifiers.
You are mixing Spring DI and CDI which are not made to work together.
Choose one of them but not both.
If you choose CDI
#Named
#ApplicationScoped
public class ProcessorFactoryImpl implements ProcessorFactory
{
#Inject
private Processor processor;
}
and
#Dependent
#Default
public class ProcessorImpl implements Processor {
// etc ...
}
In this case, the processor attribute is not a List ! You should think about what you expect. If you want a List<Processor>, you will have to use a CDI Producer instead.
If you choose Spring DI
#Component
public class ProcessorFactoryImpl implements ProcessorFactory
{
#Inject // or #Autowired
private Processor processor;
}
and
#Scope("prototype")
public class ProcessorImpl implements Processor
{
// etc ...
}
Mixing Spring and CDI
As written in the comments below, Spring can use #Inject and #Named as theses annotations are part of JSR-330.
The trouble is that too much framework mixing and using #Inject on an Instance<T>field cannot be achieved like that with Spring as it is a CDI feature.
To use the same feature, use #Provider from Spring.
Example :
CDI
#Inject
private Instance<MyClass> lazyInstance;
usage :
MyClasse instance = lazyInstance.get();
Spring
#Inject // or #Autowired
private Provider<MyClass> lazyInstance;
usage (same as CDI):
MyClasse instance = lazyInstance.get();
Have you tried List instead of Instance?
#Autowired
private List<Processor> processorList;

Spring Abstract class #Autowire null while using that field in subclass constructor

Following is the code:
public abstract class A {
#Autowired
public Provider provider;
}
#Component
public class B extends A {
B() {
provider.get();
}
}
Spring is throwing NullPointerException, while instantiating Bean of Class B.
I know #Autowired defined in Abstract class are injected, but don't know in which order they are injected.
Earlier my understanding was, While instance creation of B, Spring will autowire fields of all subclasses and then will create instance of B.
But here it seems, it overlooks the subclass concept while instance creation, and just scans B to identify #Autowire field.
Use #PostConstruct. Java Object Instantiation and Spring Dependency Injection are two different flows.
#Component
public class B extends A {
#PostConstruct
void init() {
provider.get();
}
}
If autowiring your constructors is an option the following can be helpful.
public abstract class A {
protected final Provider provider;
#Autowired
public A(Provider provider) {
this.provider = provider;
}
}
#Component
public class B extends A {
#Autowired
B(Provider provider) {
super(provider);
provider.get();
}
}
Note since the latest Spring Versions you do not need to annotate the constructor with #Autowire. If you do things right the spring framework auto-detects the constructor.

Could not autowire field when bean implements some interface with Spring

I am using Spring in my Java Application, all the #Autowired annotations working until now.
Simplified example would be:
#Component
public class MyBean implements MyInterface {
...
}
#Component
public class MyOtherBean {
#Autowired
private MyBean myBean;
...
}
Once I try to start the Application, I get:
java.lang.IllegalArgumentException: Can not set MyBean field MyOtherBean.myBean to $ProxyXX
The interface contains just two public simple methods and the class implements them.
Both classes are public and have public default constructor. (I even tried to instantiate them in tests.
Once I remove the implements section, everything works correctly.
What can be wrong with the implementation of the interface? What is $ProxyXX?
I suspect the issue is that Spring is injecting an AOP proxy which implements MyInterface - possibly for the purposes of transaction management or caching. Are any of MyBean's methods annotated #Transactional or annotated with any other annotation?
Ideally you'd probably want to reference MyBean by it's interface type - which should resolve the issue.
#Component
public class MyOtherBean {
#Autowired
private MyInterface myBean;
...
}
If you have more than one bean implementing MyInterface then you an always qualify your bean by name.
#Component
public class MyOtherBean {
#Autowired
#Qualifier("myBean")
private MyInterface myBean;
...
}
By default, Spring uses Java dynamic proxies to implement AOP when the bean implements an interface. The easiest and cleanest way to solve your problem is to make program on interfaces, and inject theinterface insted of the concrete class:
#Component
public class MyOtherBean {
#Autowired
private MyInterface myBean;
...
}
See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#aop-proxying for how to force Spring to always use CGLib.

Implement factory design pattern with spring annotaion

I have a factory class that should return me an instance of classA or classB. These classes implement interface XYZ:
interface xyz;
getInstance()
#service
classA implements xyz{
public void checkStatus(){
}
}
#service classB implements xyz{
public void checkStatus(){
}
}
Factory class:
#component
class ABCFactory{
#Autowire classA A;
public static getInstance(str a){
return classA;
}
}
Client code:
Class A a = ABCFactory.getInstance("A");
a.checkStatus();
I get null pointer exception -- probably a is returned as null?
What is the best approach to implement the factory pattern with spring annotation and autowired bean?
It's difficult to say with any certainty why your auto-wiring isn't taking place without seeing your Spring config. My first guess is that you don't have component scanning switched on:
<context:component-scan base-package="org.example"/>
Adding something like that to your spring config file (with the correct package) will tell Spring to scan the package structure for fields that need to be auto-wired, and services that can be used for auto-wiring.
static is the root of all evil. How did you managed to access classA here?
#Component
class ABCFactory{
#Autowire classA A;
public static getInstance(str a){
return classA;
}
}
A field is not static while getInstance() method is - your code won't compile.
Furthermore, dependency injection works on instances, not on static classes. Thus you should get rid of static:
#Component
class ABCFactory {
#Autowire classA A;
public xyz getInstance(str a){
return A;
}
}
and inject ABCFactory where you need it (e.g. in other services or controllers):
#Autowired
private ABCFactory factory;
BTW your design looks supicious in Spring environment, what do you want to achieve?

Resources