在这篇文章中,我们将看到如何使用Spring Boot配置JNDI数据源。JNDI数据源与JDBC数据源非常相似。JNDI数据源访问在应用程序服务器中预定义和配置并作为JNDI资源或服务发布的数据库连接。无需像使用JDBC数据源那样指定驱动程序和数据库,只需在应用程序服务器中指定JNDI资源名称。当您必须在以下环境之间移动应用程序时,JNDI可以提供帮助:开发->集成->测试->生产。如果将每个应用程序服务器配置为使用相同的JNDI名称,则每个环境中可以具有不同的数据库,但无需更改代码。您只需要在新环境中删除可部署的WAR文件。
(总体思路:在application.properties中配置JNDI名称和数据库连接信息,然后在Spring Boot应用中使用JNDI名称调用)
Oracle配置:
datasource spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver spring.datasource.url=jdbc:Oracle:thin:@//:/ spring.datasource.username=scott spring.datasource.password=tiger spring.datasource.jndiName=jdbc/myDataSource
disable schema generation from Hibernate spring.jpa.hibernate.ddl-auto=none
DB dialect - override default one spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
|
MySQL配置:
datasource spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost/roytuts spring.datasource.username=root spring.datasource.password=root spring.datasource.jndiName=jdbc/myDataSource
disable schema generation from Hibernate spring.jpa.hibernate.ddl-auto=none
|
属性配置类
创建DatabaseProperties属性类,从application.properties文件中加载数据库连接参数的键/值对。
对于Spring Boot版本1.5.9,请使用以下配置:
@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.roytuts.spring.boot.jndi.datasource.repository") public class AppConfig {
@Bean public DatabaseProperties databaseProperties() { return new DatabaseProperties(); } @Bean public TomcatEmbeddedServletContainerFactory tomcatFactory() { return new TomcatEmbeddedServletContainerFactory() { @Override protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) { tomcat.enableNaming(); return super.getTomcatEmbeddedServletContainer(tomcat); } @Override protected void postProcessContext(Context context) { ContextResource resource = new ContextResource(); resource.setName(databaseProperties().getJndiName()); resource.setType(DataSource.class.getName()); resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory"); resource.setProperty("driverClassName", databaseProperties().getDriverClassName()); resource.setProperty("url", databaseProperties().getUrl()); resource.setProperty("password", databaseProperties().getPassword()); resource.setProperty("username", databaseProperties().getUsername()); context.getNamingResources().addResource(resource); } }; } @Bean(destroyMethod = "") public DataSource jndiDataSource() throws IllegalArgumentException, NamingException { JndiObjectFactoryBean bean = new JndiObjectFactoryBean(); bean.setJndiName("java:comp/env/" + databaseProperties().getJndiName()); bean.setProxyInterface(DataSource.class); bean.setLookupOnStartup(false); bean.afterPropertiesSet(); return (DataSource) bean.getObject(); } @Bean public EntityManagerFactory entityManagerFactory() throws SQLException, IllegalArgumentException, NamingException { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setDatabase(Database.ORACLE); vendorAdapter.setShowSql(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.roytuts.spring.boot.jndi.datasource.entity"); factory.setDataSource(jndiDataSource()); factory.afterPropertiesSet(); return factory.getObject(); } @Bean public PlatformTransactionManager transactionManager() throws SQLException, IllegalArgumentException, NamingException { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory()); return txManager; } }
|
对于Spring Boot 2.2.1,请使用以下配置文件:
@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.roytuts.spring.boot.jndi.datasource.repository") public class AppConfig {
@Bean public DatabaseProperties databaseProperties() { return new DatabaseProperties(); }
@Bean public TomcatServletWebServerFactory tomcatFactory() { return new TomcatServletWebServerFactory() { @Override protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { tomcat.enableNaming(); return super.getTomcatWebServer(tomcat); }
@Override protected void postProcessContext(Context context) { ContextResource resource = new ContextResource();
resource.setType("org.apache.tomcat.jdbc.pool.DataSource"); resource.setName(databaseProperties().getJndiName()); resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory"); resource.setProperty("driverClassName", databaseProperties().getDriverClassName()); resource.setProperty("url", databaseProperties().getUrl()); resource.setProperty("password", databaseProperties().getUsername()); resource.setProperty("username", databaseProperties().getPassword());
context.getNamingResources().addResource(resource); } }; }
@Bean(destroyMethod = "") public DataSource jndiDataSource() throws IllegalArgumentException, NamingException { JndiObjectFactoryBean bean = new JndiObjectFactoryBean(); bean.setJndiName("java:comp/env/" + databaseProperties().getJndiName()); bean.setProxyInterface(DataSource.class); bean.setLookupOnStartup(false); bean.afterPropertiesSet(); return (DataSource) bean.getObject(); }
@Bean public EntityManagerFactory entityManagerFactory() throws SQLException, IllegalArgumentException, NamingException { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setDatabase(Database.MYSQL); vendorAdapter.setShowSql(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.roytuts.spring.boot.jndi.datasource.entity"); factory.setDataSource(jndiDataSource()); factory.afterPropertiesSet(); return factory.getObject(); }
@Bean public PlatformTransactionManager transactionManager() throws SQLException, IllegalArgumentException, NamingException { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory()); return txManager; }
}
|