Injection into generic parametrized property in Spring - spring

What is the best workaround for injection into generic parametrized property?
Simple example from record in Spring Jira:
#Component
public abstract class AbstractFoo<V extends Bar> {
#Autowired
protected V bar;
}
#Component
public ConcreteFoo1 extends AbstractFoo<ConcreteBar1> {
}
#Component
public ConcreteFoo2 extends AbstractFoo<ConcreteBar2> {
}
When I have such abstract AbstractFoo class and try to determine Spring bean which should be injected through generecis (ConcreteFoo1, ConcreteFoo1) Spring throws exception such as:
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'foo.ConcreteFoo1'
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [bar.Bar] is defined:
expected single matching bean but found 2: [concreteBar1, concreteBar2]
I tested similar scenarion in Spring 3.2.1.
What is the best workaround for this problem?
This problem was reported at 10/Mar/09.
Why is this functionality still not implemented in Spring? Are there any complications preventing from solving this insufficiency?

It is like if you wrote:
#Autowired
protected Bar bar;
Spring just can't understand that you want to inject ConcreteBar1
So, you can use setter injection:
public abstract class AbstractFoo<V extends Bar> {
protected V bar;
}
#Component
public class ConcreteFoo1 extends AbstractFoo<ConcreteBar1>{
#Inject
private void setBar(ConcreteBar1 bar){
this.bar = bar;
}
}

Related

Circular dependency error for beans in Spring org.springframework.beans.factory.BeanCurrentlyInCreationException:

I have a classes defined as follows :
#Configuration
public class TestConfig extends IntegrationTestConfig {
#Bean
public TestUserManager testUserManager() {
...
}
#Configuration
#Import({BaseTestConfig.class})
public class IntegrationTestConfig {
#Autowired
private TestUserManager ssbTestUserManager;
#Bean
#DependsOn({"testUserManager"})
public TestDeviceFactory testDeviceFactory() {
return new TestDeviceManager();
}
#Configuration
public class BaseTestConfig {
#Bean
public TestUserManager testUserManager() {
...
}
}
When I try to execute it, it gives the error :
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testConfig': Unsatisfied dependency expressed through field 'ssbTestUserManager'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testUserManager': Requested bean is currently in creation: Is there an unresolvable circular reference
How can I fix this issue? I am not able to override the testUserManager() method in TestConfig since it does not directly inherit from BaseTestConfig. IntegrationTestConfig and BaseTestConfig are imported as libraries so I dont have much control there.
I think #DependsOn({"testUserManager"}) is causing issue but not sure how I can resolve it
A circular reference occurs when you have a chain of beans that depends together and a cycle created in the dependency graph.
So, in your case, you've defined an instance of TestUserManager in TestConfig class and uses it in the parent class and it creates a cycle!
The solution is defininig abstract getTestUserManager method in the parent class and override it in the child class with #Bean annotation (If you are using it in other parts of code). You can use that method in your parent class instead of using the variable you've defined.
IntegrationTestConfig:
#Configuration
public abstract class IntegrationTestConfig {
public abstract TestUserManager getTestUserManager();
}
TestConfig:
#Configuration
public class TestConfig extends IntegrationTestConfig {
#Bean
#Override
public TestUserManager getTestUserManager() {
return new TestUserManager();
}
}

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.

Spring Autowired annotation with service implementation

I have few doubts in the scenario below.
Having one interface and two implementation classes:
Interface:
interface ServiceInt
{
public void save();
}
First implementation class:
Public class ServiceIntImpOne implements ServiceInt
{
public void save()
{
// I am first service implementation
}
}
Second implementation class:
Public class ServiceIntImpTwo implements ServiceInt
{
public void save()
{
// I am Second service implementation
}
}
Main class calling the save method of an implementation class:
Public class controller
{
#Autowired ServiceInt;
public void save()
{
ServiceInt.save()
}
}
My Questions:
ServiceInt.save() – which save method of service class implementation will it invoke?
How we can use the save method implementation of the ServiceIntImpTwo class?
How does autowired work?
ServiceInt.save() – which save method of service class implementation
will it invoke?
If you have two beans of the same type (beans defined via annotations or via xml) when you autowire that beans it will fail (throw exception), because Spring don't know what bean to inject.
caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [ServiceInt] is defined:
How we can use the save method implementation of the ServiceIntImpTwo
class?
If you defined your bean in a xml file, then you can use the id property
<bean id="beanTwo" class="ServiceIntImpTwo" />
then you can autowire using Qualifier annotation
#Autowired
#Qualifier("beanTwo")
ServiceInt myServiceTwo;
if you are using annotations instead.
#Component
Class ServiceIntImpTwo impl...{}
Then you can autowire
#Autowired
#Qualifier("serviceIntImpTwo ")
ServiceInt myServiceTwo;
How does autowired work?
This you can read it on Internet.
http://memorynotfound.com/handling-multiple-autowire-dependencies-with-spring-qualifier/
https://www.mkyong.com/spring/spring-autowiring-qualifier-example/
https://www.tutorialspoint.com/spring/spring_qualifier_annotation.htm
If you have two implementation to one interface you will need to provide spring hint which one to use:
you can use #Qaulifier annotation
you can use #Profile and choose the active profile.

How to do inheritance in Dao layer?

I am working with SpringMVC+Hibernate, I want to apply Inheritance in DAO layer, I am doing like below:
BaseDao.java
public interface BaseDao
{
public Serializable save(Object object) throws DataAccessException,
HibernateException;
public void merge(Object object) throws DataAccessException,
HibernateException;
public void flush() throws DataAccessException,HibernateException;
}
EmpDao.java
public interface EmpDao extends BaseDao{
}
BaseDaoImpl.java
#Repository
public class BaseDaoImpl implements BaseDao{
// Implementation for baseDao methods
}
EmpDaoImpl .java
#Repository
public class EmpDaoImpl extends BaseDaoImpl implements EmpDao{
// Implementation
}
But I am getting below error:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type
[BaseDao] is defined: expected single matching bean but found 2
What am I missing here?
If you really want to have both BaseDaoImpl and EmpDaoImpl as two beans in your Spring container, you need to tell Spring which one to use wherever you have an #Autowired field of type BaseDao using #Qualifier annotation.
Related: Understanding Spring #Autowired usage
It seems like you're trying to inject BaseDao and Spring is complaining there are two candidates.
I think this is actually a design problem. You wanted to use BaseDaoImpl both as a concrete bean that you use directly and also as a base class for other DAOs. This is bad because the sub-classes does not actually extend but simply uses their parent class. The better pattern would be to get rid of the extends and simply inject the BaseDaoImpl into the other DAOs.
Also, the interfaces looks superfluous. If you're working around the proxy problem, just use proxyTargetClass.
You can use generic types like this
BaseDao.java
public interface BaseDao<EntityType extends Object>
{
public Serializable save(EntityType entity) throws DataAccessException,
HibernateException;
public void merge(EntityType entity) throws DataAccessException,
HibernateException;
public void flush() throws DataAccessException,HibernateException;
}
BaseDaoImpl.java
#Repository
public abstract class BaseDaoImpl<EntityType extends Object> implements BaseDao<EntityType>{
// Implementation for baseDao methods
}
EmpDao.java
public interface EmpDao extends BaseDao<Employee>{
}
EmpDaoImpl .java
#Repository
public class EmpDaoImpl extends BaseDaoImpl<Employee> implements EmpDao{
// Implementation
}
You need to add the #NoRepositoryBean on the BaseDao interface so spring would not create a bean for it, as well as for EmpDao I assume

spring dependency interface injection with two implemented classes

consider a scenario of interface injection in spring, I have an interface which was implemented by two class. If we inject the Interface in another class using #Autowired. Now if we call a method in that interface then which class implemented method will be called? consider that we are not using #Qualifier annotation.
enter code here
public interface EmployeeDAOI{
void save();
}
public class Emp1 implements EmployeeDAOI{
public void save(){
//some logic
}
}
public class Emp2 implements EmployeeDAOI{
public void save(){
//some logic
}
}
now we inject EmployeeDAOI to some class
public class IterfaceEx{
#Autowired
private EmployeeDAOI edaoi;
public void setEmployeeDAOI(EmployeeDAOI edaoi){
this.edaoi=edaoi;
}
edaoi.save(); // My question is here which class method will be called ?
}
None.
You get an exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [EmployeeDAOI] is defined: expected single matching bean but found 2: [emp1 , emp2]
Spring expects exactly one instance, unless the injection is done for a Collection of those instances or you use a way of differentiating (#Qualifier).

Resources