使用Spring Boot配置JNDI数据源 -Roy教程


在这篇文章中,我们将看到如何使用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;
    }

}

[b]详细点击标题见原文[/b]