如何在声明中将(绑定)对象放到jndi中?

yet*_*der 9 java configuration spring jndi

我们有一个普通的独立spring应用程序,我们需要将jdbc数据源放在jndi中.(我们使用jboss treecache,它需要数据源在jndi中).

一些谷歌搜索发现大多数使用spring的jndi-lookup示例,其中一个对象已经放入jndi(通过tomcat或应用程序服务器等),但我们还需要:我有一个普通的数据源Spring bean,我注入其他服务,但我无法将其注入TreeCache,因为它只需要来自jndi.

找到org.springframework.jndi.JndiTemplate,可以声明为bean,例如:

<bean id="fsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</prop>
            <prop key="java.naming.provider.url">file:///c:\windows\temp</prop>
        </props>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

但是没有找到如何在java代码中绑定它:fsJndiTemplate.bind(name, obj)来自其他bean的init-method.有没有办法以声明方式做到这一点?

Spi*_*ina 13

谢谢你的问题.我写了一个Treydone解决方案的变体,并认为在这里使用实际代码可能很有用(因为它很短):

public class JndiExporter implements InitializingBean {

    private final JndiTemplate template = new JndiTemplate();

    private Map<String, Object> jndiMapping = null;

    @Override
    public void afterPropertiesSet() throws Exception {
            for(Entry<String, Object> addToJndi: jndiMapping.entrySet()){
                    template.bind(addToJndi.getKey(), addToJndi.getValue());
            }
    }

    public void setJndiMapping(Map<String, Object> jndiMapping) {
            this.jndiMapping = jndiMapping;
    }

}
Run Code Online (Sandbox Code Playgroud)

请注意,我实现了InitializingBean而不是BeanFactoryAware.这允许配置(带引用),如下所示:

<bean id="jndiExporter" class="com.ra.web.util.JndiExporter">
    <property name="jndiMapping">
        <map>
            <entry key="bean1" value-ref="other_spring_bean_id" />
            <entry key="bean2" value="literal_value" />
        </map>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)


Vin*_*ers 7

您可以创建一个JndiExporter,它使用JndiTemplate将对象的地图与名称绑定在一起:

<bean id="jndiExporter" class="org.xxx.JndiExporter">
    <property name="jndiTemplate" ref="jndiTemplate">
    <property name="objects">
          <map>
            <entry key="name1" value="bean1"/>
            <entry key="name2" value="bean2"/>
            <entry key="name3" value="bean3"/>
            <entry key="name4" value="bean4"/>
          </map>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

您的JndiExporter必须实现BeanFactoryAware以使用注入的BeanFactory检索spring bean.

这可能是一个:)


sup*_*rEb 6

我意识到这是一个老问题,但有一种方法可以在没有自定义代码的情况下完成此操作.它相当冗长,但100%声明.

<!-- inside container, use JndiTemplate -->
<bean id="jndiBinder" class="org.springframework.jndi.JndiTemplate"/>
<!-- outside container (e.g. for tests), use SimpleNamingContextBuilder -->
<!-- <bean id="jndiBinder" class="org.springframework.mock.jndi.SimpleNamingContextBuilder" factory-method="emptyActivatedContextBuilder"/> -->

<!-- use MethodInvokingFactoryBean to call 'bind' on 'jndiBinder' -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="jndiBinder"/>
    <property name="targetMethod" value="bind"/>
    <property name="arguments">
        <array>
            <value type="java.lang.String">java:comp/UserTransaction</value>
            <ref bean="atomikosUserTransaction"/>
        </array>
    </property>
</bean>

<!-- define as many bindings as you need -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="jndiBinder"/>
    <property name="targetMethod" value="bind"/>
    <property name="arguments">
        <array>
            <value type="java.lang.String">another/jndi/name</value>
            <value>literal_value</value>
        </array>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

MethodInvokingFactoryBean也可用于设置系统属性(使用Atomikos公司时非常便利),只要该读取系统属性中的豆depends-on那个MethodInvokingFactoryBean.

<bean id="atomikosSystemProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <bean class="java.lang.System" factory-method="getProperties"/>
    </property>
    <property name="targetMethod" value="putAll"/>
    <property name="arguments" ref="atomikosJtaProps"/>
</bean>
<bean id="atomikosJtaProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
        <props>
            <prop key="com.atomikos.icatch.no_file">true</prop>
            <prop key="com.atomikos.icatch.hide_init_file_path">true</prop>
            <prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop>
            <prop key="com.atomikos.icatch.log_base_dir">/opt/txlogs</prop>
        </props>
    </property>
</bean>
<bean id="atomikosUserTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce" depends-on="atomikosSystemProps"/>
Run Code Online (Sandbox Code Playgroud)