• Springboot解决Main方法启动无法注入JNDI


    Springboot解决Main方法启动无法注入JNDI

    上一篇Springboot配置外部容器使用JNDI读取数据源,讲到部署到web容器如何使用JNDI读取数据源。

    那么在开发时Main方法启动怎么使用JNDI读取数据源??

    需求

    仅在dev环境下解决main方法无法注入JNDI,生产和测试需要部署在web容器中

    步骤

    • 配置application-dev.yml
    ## 仅在dev环境下注入有效,解决main方法无法注入JNDI—— @Profile("dev")
    jndi:
      dev:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.xxx.xxx:3306/test
        username: root
        password: root
    
    • 配置JndiDevConfig
    package cn.pconline.config.dev;
    
    import org.apache.catalina.Context;
    import org.apache.catalina.startup.Tomcat;
    import org.apache.tomcat.util.descriptor.web.ContextResource;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
    import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
    import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Profile;
    
    import javax.sql.DataSource;
    
    /**
     * @Description 仅在dev环境下有效解决main方法无法注入JNDI
     *              生产和测试需要部署在web容器中
     * https://412887952-qq-com.iteye.com/blog/2429442
     * @Author jie.zhao
     * @Date 2019/7/31 14:19
     */
    @Configuration
    @Profile("dev")
    public class JndiDevConfig {
    
        @Value("${spring.datasource.jndi-name}")
        private String jndiName;
    
        @Value("${jndi.dev.driver-class-name}")
        private String driverClassName;
    
        @Value("${jndi.dev.url}")
        private String url;
    
        @Value("${jndi.dev.username}")
        private String username;
    
        @Value("${jndi.dev.password}")
        private String password;
    
        @Bean
        public ServletWebServerFactory servletContainer() {
            TomcatServletWebServerFactory tomcat = 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.setName(jndiName);
                    resource.setType(DataSource.class.getName());
                    resource.setProperty("driverClassName", driverClassName);
                    resource.setProperty("url", url);
                    resource.setProperty("username", username);
                    resource.setProperty("password", password);
                    context.getNamingResources().addResource(resource);
                    super.postProcessContext(context);
                }
            };
            return tomcat;
        }
    }
    
    
    • 启动报错
    SpringBoot JNDI datasource throws java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory
    

    原因是缺少依赖

    <!--解决Dev环境下mian方法使用JNDI连接池,正式打包不需要 provided-->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-dbcp</artifactId>
        <version>8.5.4</version>
        <scope>provided</scope>
    </dependency>
    

    参考文档:

    https://412887952-qq-com.iteye.com/blog/2429442

    https://stackoverflow.com/questions/39284947/springboot-jndi-datasource-throws-java-lang-classnotfoundexception-org-apache-t

    -------------已经触及底线 感谢您的阅读-------------
  • 相关阅读:
    NoSuchMethodError 一般是jar包冲突了
    联通网络环境上无法访问http://repo1.maven.org/maven2/中央库解决,镜像库添加
    实现MySQL数据库的实时备份
    海外支付:遍布全球的Paypal
    .Net分布式缓存应用实例:Couchbase
    海外支付:抵御信用卡欺诈的CyberSource
    那些年,我们开发的接口之:QQ登录(OAuth2.0)
    ES6知识整理(一)--- let/const/箭头函数
    webpack 热更新(实施同步刷新)
    Vue状态管理vuex
  • 原文地址:https://www.cnblogs.com/cnsyear/p/12913341.html
Copyright © 2020-2023  润新知