vicky
vicky

Reputation: 2149

Spring-Core JNDI Configuration with beans

Lets take I have a class as shown below :

public interface UserDAO {
    public List<User> list();
}

public class UserDAOImpl implements UserDAO {
    private DataSource dataSource;

    public UserDAOImpl(DataSource dataSource) {
        this.dataSource = dataSource;
 }

Let's assume JNDI configuration is done correctly in tomcat.

Now for spring bean mapping in many sites I found the below configuration:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/UsersDB"/>
</bean>

    <bean id="userDao" class="net.codejava.spring.dao.UserDAOImpl">
    <constructor-arg>
        <ref bean="dataSource" />
    </constructor-arg>
</bean>

Here is what my question , UserDAOImpl class is looking for DataSource object but we are injecting JndiObjectFactoryBean object[Which is not a subclass of DataSource] , since we are not even mentioning the factory method how or where the conversion is happening ?

Upvotes: 3

Views: 1213

Answers (2)

madteapot
madteapot

Reputation: 2294

JndiObjectFactoryBean is bean of type org.springframework.beans.factory.FactoryBean. This beans are used as a factory for an object to expose. Below are excerpts from the javadoc for FactoryBean;

Interface to be implemented by objects used within a BeanFactory which are themselves factories for individual objects. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.

NB: A bean that implements this interface cannot be used as a normal bean. A FactoryBean is defined in a bean style, but the object exposed for bean references (getObject()) is always the object that it creates.

FactoryBeans can support singletons and prototypes, and can either create objects lazily on demand or eagerly on startup. The SmartFactoryBean interface allows for exposing more fine-grained behavioral metadata.

So when spring framework is autowiring the datasource to useDaoImpl it checks whether dataSource is a bean of type FactoryBean which it is in this case so it will assign the object from getObject() method of JndiObjectFactoryBean to the dataSource. If you want to understand this more take a look at ClassPathXmlApplicationContext.finishBeanfactoryInitialization(..) and DefaultListableBeanFactory.preInstantiateSingletons() methods which perform the autowiring in this case.

Upvotes: 1

rvillablanca
rvillablanca

Reputation: 1646

I don't know how it is done but Spring Frameworks knows that beans is a Factory of DataSource beans, then it can inject the discovered datasource in your others beans.

I you want to know how it is done then you can look at the source code in Spring Framework Github

Upvotes: 0

Related Questions