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>
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
}
これが過去に直面した問題であることに気付かずにここに着陸しました--- 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
}