为什么使用 JndiObjectFactoryBean 配置 JNDI 数据源不起作用?
why use JndiObjectFactoryBean to config JNDI datasource did not work?
当我使用 Java-base 来配置我的 JNDI 时。 Spring4.2.5.
但是如果我使用 JndiObjectFactoryBean config.when 我想得到 datasource
,对象将为空。
@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 方法 return 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
}
我来到这里并没有意识到这是我过去遇到的问题 -
因此,解决方法(不是首选方法)是在尝试 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
}
对于那些正在寻找通过 JNDI 定义数据源的方法的人,我会选择:
@Bean
public JndiObjectFactoryBean dataSource(){
return new JndiDataSourceLookup().getDataSource("jdbc/SpittrDS");
}
当我使用 Java-base 来配置我的 JNDI 时。 Spring4.2.5.
但是如果我使用 JndiObjectFactoryBean config.when 我想得到 datasource
,对象将为空。
@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 方法 return 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
}
我来到这里并没有意识到这是我过去遇到的问题 -
因此,解决方法(不是首选方法)是在尝试 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
}
对于那些正在寻找通过 JNDI 定义数据源的方法的人,我会选择:
@Bean
public JndiObjectFactoryBean dataSource(){
return new JndiDataSourceLookup().getDataSource("jdbc/SpittrDS");
}