带有 bean 的 Spring-Core JNDI 配置

Posted

技术标签:

【中文标题】带有 bean 的 Spring-Core JNDI 配置【英文标题】:Spring-Core JNDI Configuration with beans 【发布时间】:2017-08-04 22:32:37 【问题描述】:

让我有一个如下所示的课程:

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


public class UserDAOImpl implements UserDAO 
    private DataSource dataSource;

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

假设 JNDI 配置在 tomcat 中正确完成。

现在对于许多站点中的 spring bean 映射,我发现了以下配置:

<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>

这是我的问题,UserDAOImpl 类正在寻找 DataSource 对象,但我们正在注入 JndiObjectFactoryBean 对象[这不是 DataSource 的子类],因为我们甚至没有提到工厂方法如何或在何处发生转换?

【问题讨论】:

【参考方案1】:

JndiObjectFactoryBeanorg.springframework.beans.factory.FactoryBean 类型的 bean。此 bean 用作要公开的对象的工厂。以下是 FactoryBean 的 javadoc 的摘录;

由 BeanFactory 中使用的对象实现的接口,这些对象本身就是各个对象的工厂。如果一个 bean 实现了这个接口,它被用作一个对象的工厂来暴露,而不是直接作为一个将自己暴露的 bean 实例。

注意:实现此接口的 bean 不能用作普通 bean。 FactoryBean 以 bean 样式定义,但为 bean 引用 (getObject()) 公开的对象始终是它创建的对象

FactoryBeans 可以支持单例和原型,并且可以按需懒惰地创建对象,也可以在启动时急切地创建对象。 SmartFactoryBean 接口允许公开更细粒度的行为元数据。

因此,当 Spring 框架将数据源自动装配到 useDaoImpl 时,它会检查 dataSource 是否是 FactoryBean 类型的 bean,在这种情况下,它会将对象从 JndiObjectFactoryBeangetObject() 方法分配给数据源。如果您想进一步了解这一点,请查看在这种情况下执行自动装配的 ClassPathXmlApplicationContext.finishBeanfactoryInitialization(..)DefaultListableBeanFactory.preInstantiateSingletons() 方法。

【讨论】:

谢谢,明白了。【参考方案2】:

我不知道它是如何完成的,但 Spring Frameworks 知道 bean 是 DataSource bean 的工厂,然后它可以将发现的数据源注入到您的其他 bean 中。

我想知道它是怎么做的可以看Spring Framework Github的源代码

【讨论】:

以上是关于带有 bean 的 Spring-Core JNDI 配置的主要内容,如果未能解决你的问题,请参考以下文章

2Spring之核心容器

解决jar包冲突问题

鸟瞰spring

spring——bean的创建过程

Spring

Spring源码解读之核心容器下节