web-dev-qa-db-ja.com

JndiObjectFactoryBeanを使用してJNDIデータソースを構成しないのはなぜですか?

jNDIを構成するためにJavaベースを使用するとき。春4.2.5。

しかし、JndiObjectFactoryBeanを使用してconfig.whenを取得したい場合、datasourceを取得すると、オブジェクトはnullになります。

@Bean
    public DataSource dataSource(){
        JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(DataSource.class);
        return (DataSource) jndiObjectFactoryBean.getObject();  //NULL!!!
    }

しかし、これに方法を変更すれば、うまくいきます。

@Bean
    public DataSource dataSource(){
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        DataSource dataSource = dsLookup.getDataSource("Java:comp/env/jdbc/SpittrDS");
        return dataSource;
    }

どこに問題があるのか​​わかりません。

Tomcat 9.0 context.xml

<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <Resource name="jdbc/SpittrDS"
      auth="Container"
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/spittrds"
      username="root"
      password="1"
      maxActive="100"
      maxIdle="20"
      minIdle="5"
      maxWait="10000"/>
</Context>
7
TIMFUNNY

JndiObjectFactoryBeanでの実際のルックアップは、ライフサイクルコールバックメソッドで実行されます。このように@Beanメソッドで明示的にメソッドを呼び出す(回避策)

    @Bean
    public DataSource dataSource(){
        JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(DataSource.class);
        jndiObjectFactoryBean.afterPropertiesSet();
        return (DataSource) jndiObjectFactoryBean.getObject();  //NULL!!!
    }

またはより良いアプローチ。 @BeanメソッドがJndiObjectFactoryBeanを返し、そのライフサイクルを管理できるようにします。次に、データソースを必要とする依存Beanに、ファクトリから作成されたデータソースを注入します。

    @Bean
    public JndiObjectFactoryBean dataSource(){
        JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(DataSource.class);
        return jndiObjectFactoryBean;
    }

//in your dependnecy

@Bean
public SomeBean someBean(DataSource dataSource){
   //use the injected datasource shich comes from the factory
}
8
ekem chitsiga

これが過去に直面した問題であることに気付かずにここに着陸しました--- SpringのJndiObjectFactoryBeanをSolaceのConnectionFactoryにキャストする際のエラー-MQ JMS

したがって、回避策(推奨される方法ではありません)は、getObject()を試行する前に、jndiObjectFactoryBeanでafterPropertiesSet()を呼び出すことです。

@Bean
    public DataSource dataSource(){
        JndiObjectFactoryBean jndiObjectFactoryBean =new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(DataSource.class);
        jndiObjectFactoryBean.afterPropertiesSet();
        return (DataSource) jndiObjectFactoryBean.getObject();  //NOT NULL
    }
1
ObviousChild