我有一个使用Spring Boot构建的小型Web应用程序,它有两个数据源(一个用于应用程序数据,另一个用于检索用户访问信息)。我已经使用每个数据源的配置类并使用application.properties文件中的数据源连接详细信息成功配置了这个。
我现在正在尝试重构这个以使用jndi查找数据源详细信息,以便我可以在本地使用相同的方法,因为我将在dev / test和prod中使用。
我修改了我的数据库配置类以使用jndi查找,现在我正在Spring Tool Suite中提供的Pivotal tc服务器上运行我的应用程序。
目前我可以看到其中一个数据源配置正确(我在应用程序启动时从表中返回记录计数)。但是我的第二个数据源似乎没有正确配置,我得到一个例外......
java.sql.SQLException: The url cannot be null
at java.sql.DriverManager.getConnection(DriverManager.java:556) ~[na:1.7.0_40]
at java.sql.DriverManager.getConnection(DriverManager.java:187) ~[na:1.7.0_40]
at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:308) ~[tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:716) [tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:648) [tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:468) [tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:143) [tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.4.jar:na]
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.4.jar:na]
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:342) [spring-jdbc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection.isEmbedded(EmbeddedDatabaseConnection.java:139) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate.getDefaultDdlAuto(JpaProperties.java:224) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate.getOrDeduceDdlAuto(JpaProperties.java:212) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate.getAdditionalProperties(JpaProperties.java:188) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate.access$000(JpaProperties.java:129) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.getHibernateProperties(JpaProperties.java:126) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.isInitializingDatabase(DataSourceInitializedPublisher.java:80) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.postProcessAfterInitialization(DataSourceInitializedPublisher.java:68) [spring-boot-autoconfigure-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1723) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1600) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:448) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1214) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1214) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776) [spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) [spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) [spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:150) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:130) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5156) [catalina.jar:na]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:na]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) [catalina.jar:na]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) [catalina.jar:na]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) [catalina.jar:na]
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:586) [catalina.jar:8.0.26.B]
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1750) [catalina.jar:8.0.26.B]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_40]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_40]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_40]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_40]
at java.lang.Thread.run(Thread.java:724) [na:1.7.0_40]
我的application.properties文件具有以下属性
spring.datasource.jndi-name=java:comp/env/jdbc/app_datasource
spring.datasource.expected-type=javax.sql.DataSource
security.datasource.jndi-name=java:comp/env/jdbc/security_datasource
security.datasource.expected-type=javax.sql.DataSource
我的数据库配置类看起来像这样..
@Configuration
@EnableConfigurationProperties
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
public class AppDBConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public JndiPropertyHolder primary() {
return new JndiPropertyHolder();
}
@Bean(name = "app")
@Primary
public DataSource appDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(primary().getJndiName());
return dataSource;
}
}
@Configuration
@EnableConfigurationProperties
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
public class SecurityDBConfig {
@Bean
@ConfigurationProperties(prefix = "security.datasource")
public JndiPropertyHolder security() {
return new JndiPropertyHolder();
}
@Bean(name = "security")
public DataSource securityDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(security().getJndiName());
return dataSource;
}
}
,server.xml看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<Server port="${base.shutdown.port}" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<Listener className="com.springsource.tcserver.serviceability.deploy.TcContainerDeployer"/>
<Listener accessFile="${catalina.base}/conf/jmxremote.access" address="127.0.0.1" authenticate="true" className="com.springsource.tcserver.serviceability.rmi.JmxSocketListener" passwordFile="${catalina.base}/conf/jmxremote.password" port="${base.jmx.port}" useSSL="false"/>
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
<Service name="Catalina">
<Executor maxThreads="300" minSpareThreads="50" name="tomcatThreadPool" namePrefix="tomcat-http--"/>
<Engine defaultHost="localhost" name="Catalina">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host appBase="webapps" autoDeploy="true" deployOnStartup="true" deployXML="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log." suffix=".txt"/>
<Context docBase="bsc" path="/bsc" reloadable="true" source="org.eclipse.jst.jee.server:bsc">
<Resource auth="Container" defaultAutoCommit="true" driverClassName="com.sybase.jdbc3.jdbc.SybDriver" maxActive="20" maxIdle="30000" maxWait="100" name="jdbc/security_datasource" password="securityPassword" removeAbandoned="true" removeAbandonedTimeout="15" type="javax.sql.DataSource" url="jdbc:sybase:Tds:server.systems.uk.co:10010/security_database" username="securityUserName"/>
<Resource auth="Container" defaultAutoCommit="true" driverClassName="net.sourceforge.jtds.jdbc.Driver" maxActive="20" maxIdle="30000" maxWait="100" name="jdbc/app_datasource" password="appPassword" removeAbandoned="true" removeAbandonedTimeout="15" type="javax.sql.DataSource" url="jdbc:jtds:sybase://server.systems.uk.co:10010/app_database" username="appUserName"/>
</Context>
</Host>
</Engine>
<Connector maxHttpHeaderSize="1508192" acceptCount="100" connectionTimeout="20000" executor="tomcatThreadPool" maxKeepAliveRequests="15" port="${bio.http.port}" protocol="org.apache.coyote.http11.Http11Protocol" redirectPort="${bio.https.port}"/>
</Service>
</Server>
任何人都可以看到为什么我的第二个数据源没有配置?这是一个生命周期时间问题吗?正如我所说主数据源配置正确但安全性失败
更新
JndiPropertyHolder只是一个简单的便利类,如下所示
import org.springframework.stereotype.Component;
@Component
public class JndiPropertyHolder {
private String jndiName;
public String getJndiName() {
return this.jndiName;
}
public void setJndiName(final String jndiName) {
this.jndiName = jndiName;
}
}
答案 0 :(得分:1)
I have achieved this successfully by configuring my spring boot project as mentioned below :
//1. Application.java
//package hello;
//
//import javax.sql.DataSource;
//
//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
//import org.springframework.boot.builder.SpringApplicationBuilder;
//import org.springframework.boot.web.support.SpringBootServletInitializer;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.ComponentScan;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.jdbc.core.JdbcTemplate;
//import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
//
//import hello.utilspackage.Foo;
//import springfox.documentation.builders.PathSelectors;
//import springfox.documentation.builders.RequestHandlerSelectors;
//import springfox.documentation.spi.DocumentationType;
//import springfox.documentation.spring.web.plugins.Docket;
//import springfox.documentation.swagger2.annotations.EnableSwagger2;
//
//@Configuration
//@ComponentScan
//@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer {
private final Log logg = LogFactory.getLog(getClass());
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
logg.info("Server startup data loading started");
new Foo().bar();
logg.info("Server startup data loading completed");
return application.sources(applicationClass);
}
@Configuration
public class Config {
@Value("${foo.spring.datasource.jndi-name}")
private String primaryJndiName;
@Value("${bar.spring.datasource.jndi-name}")
private String secondaryJndiName;
@Primary
@Bean(destroyMethod = "")
public DataSource primaryDs() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource(primaryJndiName);
}
@Bean(destroyMethod = "")
public DataSource secondaryDs() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return lookup.getDataSource(secondaryJndiName);
}
}
@Configuration
public class ConfigJdbcTemplates {
@Value("${foo.spring.datasource.jndi-name}")
private String primaryJndiName;
@Value("${bar.spring.datasource.jndi-name}")
private String secondaryJndiName;
@Primary
@Bean(destroyMethod = "")
public JdbcTemplate primaryJT() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return new JdbcTemplate(lookup.getDataSource(primaryJndiName));
}
@Bean(destroyMethod = "")
public JdbcTemplate secondaryJT() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
return new JdbcTemplate(lookup.getDataSource(secondaryJndiName));
}
}
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
}
private static Class<Application> applicationClass = Application.class;
}
Observe the class Config in above code snippet , it has been annotated with @Configuration and one of the datasources in it is declared as @Primary
//GreetingController.java
//package hello;
//
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//import java.util.concurrent.atomic.AtomicLong;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.jdbc.core.JdbcTemplate;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RequestParam;
//import org.springframework.web.bind.annotation.RestController;
//
//import hello.Application.Config;
//
//@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@Autowired
Config conf;
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
String ss = null;
List<Map<String, Object>> a = new JdbcTemplate(conf.secondaryDs())
.queryForList("SELECT * from secondaryDB");
for (Map<String, Object> map : a) {
Set<String> kkeys = map.keySet();
for (String string : kkeys) {
if (map.get(string) != null)
ss += string + " -- " + map.get(string).toString() + "## ";
}
}
return new Greeting(counter.incrementAndGet(), String.format(template, ss));
}
@RequestMapping("/")
public Greeting greetingBlank() throws Exception {
String ss = null;
List<Map<String, Object>> a = new JdbcTemplate(conf.primaryDs()).queryForList(
"SELECT * from primaryDB");
for (Map<String, Object> map : a) {
Set<String> kkeys = map.keySet();
for (String string : kkeys) {
if (map.get(string) != null)
ss += string + " -- " + map.get(string).toString() + "## ";
}
}
return new Greeting(counter.incrementAndGet(), String.format(template, ss));
}
}
Now in one of my rest controllers i.e. in GreetingController class I can safely use the @Autowired Config config instance.So that we can use new JdbcTemplate(conf.secondaryDs())
for querying the database referred by the Secondary datasource. OR new JdbcTemplate(conf.primaryDs())
for querying the database referred by the Primary datasource
**Same can be achieved by configuring JdbcTemplates in Application.class , for this observe the class ConfigJdbcTemplates in Application.java. Please have a look at below implementation in controller DatabasePrimaryQueryController
//DatabasePrimaryQueryController.java
//package hello;
//
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//import java.util.concurrent.atomic.AtomicLong;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import hello.Application.ConfigJdbcTemplates;
//
//@RestController
public class DatabasePrimaryQueryController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@Autowired
ConfigJdbcTemplates confJts;
@RequestMapping("/queryforpas")
public Greeting greeting() throws Exception {
String ss = null;
List<Map<String, Object>> a = confJts.secondaryJT()
.queryForList("SELECT * from secondaryDB");
for (Map<String, Object> map : a) {
Set<String> kkeys = map.keySet();
for (String string : kkeys) {
if (map.get(string) != null)
ss += string + " -- " + map.get(string).toString() + "## ";
}
}
return new Greeting(counter.incrementAndGet(), String.format(template, ss));
}
@RequestMapping("/queryforods")
public Greeting greetingBlank() throws Exception {
String ss = null;
List<Map<String, Object>> a = confJts.primaryJT().queryForList(
"SELECT * from primaryDB");
for (Map<String, Object> map : a) {
Set<String> kkeys = map.keySet();
for (String string : kkeys) {
if (map.get(string) != null)
ss += string + " -- " + map.get(string).toString() + "## ";
}
}
return new Greeting(counter.incrementAndGet(), String.format(template, ss));
}
}
Both of the above methods are working as per expectations the only difference is that in the first implementation I'm autowiring datasources and in second implementation Jdbctemplate is Autowired.
My application.properties file is as below
server.servlet-path=/*
server.port=7877
foo.spring.datasource.jndi-name=java:/PrimaryDB
bar.spring.datasource.jndi-name=java:/SecondaryDB
This application is deployed on jboss eap 6.4 where the jndi-names are bound with DataSource details from jboss' standalone.xml