Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to inject parent class dependencies with Spring annotations

I have following code -

Dao.java

@Component
public class Dao extends NamedParameterJdbcDaoSupport {

}

dbContext.xml

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName" value="${db.driver}" />
            <property name="url" value="${db.jdbc.url}" />
            <property name="username" value="${db.user}" />
            <property name="password" value="${db.password}" />
        </bean>

applicationContext.xml

<context:component-scan base-package="com.kshitiz" />

The problem is that NamedParameterJdbcDaoSupport needs data source in order to work. Since this is a property of the super class and not my own class the only way I could think of to make it work is -

@Component
public class Dao extends NamedParameterJdbcDaoSupport {
    @Autowired
    public void setDataSource(DataSource dataSource) {
        super.setDataSource(dataSource);
    }
}

This is pretty ugly. Can I specify that I want to autowire all the properties of my bean? Something like -

@Component(default-autowire="byType")
public class Dao extends NamedParameterJdbcDaoSupport {

}

Is this possible in Spring? Alternatively what is the most elegant way to inject super class dependencies?

Edit: I already know this can be done using XML which I am presently using. I'd like to know the best that can be done using annotations only.

like image 489
Kshitiz Sharma Avatar asked May 24 '13 11:05

Kshitiz Sharma


People also ask

Which annotations can be used for injecting dependencies in Spring?

@Autowired annotation is used to let Spring know that autowiring is required. This can be applied to field, constructor and methods. This annotation allows us to implement constructor-based, field-based or method-based dependency injection in our components.

What are ways to inject dependency in Spring?

The Spring-Core module is responsible for injecting dependencies through either Constructor or Setter methods. The design principle of Inversion of Control emphasizes keeping the Java classes independent of each other and the container frees them from object creation and maintenance.

Which annotations are used for dependency injection?

Dependency injection is simply an easier-to-program alternative to using the javax interfaces or JNDI APIs to look up resources. A field or a method of an application component can be annotated with the @Resource annotation.

Which type of dependency injection is better in Spring?

We can combine constructor-based and setter-based types of injection for the same bean. The Spring documentation recommends using constructor-based injection for mandatory dependencies, and setter-based injection for optional ones.


2 Answers

Not necessarily the answer you were looking for, but I would do this with an intermediary super class.

public abstract class AbstractDao extends NamedParameterJdbcDaoSupport {
    @Autowired
    public void setDataSource(DataSource dataSource) {
        super.setDataSource(dataSource);
    }
}

@Component
public class Dao extends AbstractDao {
}
like image 100
Zutty Avatar answered Sep 22 '22 15:09

Zutty


I've searched for something similar when using Spring's Hibernate support. There's no way of adding (or changing) the wiring in a superclass without subclassing and overriding the required method. Or the declarative approach of subclassing and providing a ref value for the desired properties via XML.

Anything less "ugly" would probably be less transparent. So Zutty's proposed solution fits best here as it eliminates the need of overriding in each Dao implementation.

like image 29
BrokenMill Avatar answered Sep 23 '22 15:09

BrokenMill