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>
参考文档: