使用Spring Boot配置JNDI資料來源 -Roy教程

banq發表於2020-02-26

在這篇文章中,我們將看到如何使用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]

 

相關文章