springboot jndi禁用

本文主要介绍了在SpringBoot高版本中运行war包时遇到的JNDI查询问题,以及如何通过配置`spring.jndi.ignore=true`来解决。问题出现在高版本由于引入了JNDI查询,导致找不到特定的JNDI名称。解决方案是在项目根目录下创建`springs.properties`文件,并设置相应属性。文章详细解析了配置的原理,以及配置的读取过程。
摘要由CSDN通过智能技术生成

摘要:在实际项目开发中使用springboot的时候,可以使用jar包的方式运行项目,也可以将springboot项目打成war包使用。springboot war包运行可能会出现 [localhost-startStop-1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/LOGGING.pattern_level] not found - trying original name [LOGGING.pattern_level]. javax.naming.NameNotFoundException: Name [LOGGING.pattern_level] is not bound in this Context. Unable to find [LOGGING.pattern_level]

。反正就是诸如此类的问题吧。

上述的问题,在高版本的spring boot中会出现的,低版本不会出现这个问题。因为高版本中引入了JNDI查询的操作。

解决方案:

在项目的根目录中新建spring.properties配置文件,如下图所示:

    添加属性以及值,如下所示:

spring.jndi.ignore=true

原理

打开StandardServletEnvironment类,该类中的customizePropertySources方法如下:

public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
}
    super.customizePropertySources(propertySources);
}
JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()代码如下:
public static final String IGNORE_JNDI_PROPERTY_NAME = "spring.jndi.ignore";
private static final boolean shouldIgnoreDefaultJndiEnvironment =
SpringProperties.getFlag(IGNORE_JNDI_PROPERTY_NAME);
public static boolean isDefaultJndiEnvironmentAvailable() {
//如果忽略jndi则返回false
if (shouldIgnoreDefaultJndiEnvironment) {
return false;
}
    try {
                  //准备jndi环境
        new InitialContext().getEnvironment();
        return true;
}
catch (Throwable ex) {
        return false;
}
}


通过上文可知:

1、如果我们需要忽略jndi则可以配置spring.jndi.ignore值为true即可。

2、在哪里配置呢?我们不妨跟进SpringProperties类中的getFlag方法。

spring.jndi.ignore获取原理

SpringProperties类的getFlag方法如下所示:

public static boolean getFlag(String key) {
    return Boolean.parseBoolean(getProperty(key));
}
继续跟进getProperty方法,如下所示:

public static String getProperty(String key) {
       //获取spring.jndi.ignore值
String value = localProperties.getProperty(key);
if (value == null) {
    try {//获取系统的变量
    value = System.getProperty(key);
    }
        catch (Throwable ex) {
    }
    }
    return value;
}


上述的方法可以总结如下:

从localProperties集合中获取spring.jndi.ignore属性,如果没有获取到则直接从环境变量中进行获取。localProperties集合在哪里初始化的呢?我们看一下SpringProperties类中的静态代码块,如下所示:

private static final String PROPERTIES_RESOURCE_LOCATION = "spring.properties";
static {
try {
    ClassLoader cl = SpringProperties.class.getClassLoader();
    URL url = (cl != null ? cl.getResource(PROPERTIES_RESOURCE_LOCATION) :ClassLoader.getSystemResource(PROPERTIES_RESOURCE_LOCATION));
    if (url != null) {
        logger.info("Found 'spring.properties' file in local classpath");
        InputStream is = url.openStream();
        try {
            localProperties.load(is);
        }
        finally {
            is.close();
            }
    }
    }
catch (IOException ex) {
}
}


看到上面的代码,我们明白了,原来这里是直接读取跟目录中的spring.properties文件中的所有属性。看到这里,焕然大悟。原来如此。
 

其他可参考链接:JNDI学习总结(一):JNDI到底是什么?_wn084的博客-CSDN博客

### 回答1: Spring Boot可以通过配置JNDI数据源来连接数据库。具体步骤如下: 1. 在Tomcat的conf/server.xml文件中添加数据源配置,例如: ``` <Resource name="jdbc/myDataSource" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="myuser" password="mypassword" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydatabase"/> ``` 2. 在Spring Boot的application.properties文件中添加JNDI数据源的配置,例如: ``` spring.datasource.jndi-name=java:comp/env/jdbc/myDataSource ``` 3. 在Spring Boot的启动类中添加注解@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}),排除自动配置的数据源,例如: ``` @SpringBootApplication @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 这样就可以使用JNDI数据源连接数据库了。 ### 回答2: Spring Boot是一种快速开发Web应用程序的框架,并且集成了许多常用的框架和库,其自带的tomcat默认使用了DBCP(Apache Common DBCP)连接池框架作为数据源,但是实际项目存在多种数据源的需求,这时候我们就可以通过配置JNDI来实现多数据源的配置。 JNDIJava Naming and Directory Interface)是Java命名和目录接口,JNDI数据源就是将数据库的信息绑定到JNDI命名空间中,使Web应用程序可以访问并使用它们。Spring Boot可以使用JNDI数据源来连接各种数据库,只需要在应用程序的配置文件中添加如下配置: ```yaml spring: jndi: name: java:comp/env/jdbc/mydatasource ``` 此配置告诉Spring Boot去查找一个名为“java:comp/env/jdbc/mydatasource”的JNDI数据源并使用它。但是,我们还需要在Tomcat服务器中创建一个名为“jdbc/mydatasource”的JNDI数据源,并将其绑定到数据库上: 1. 打开Tomcat服务器的目录,找到server.xml文件,在GlobalNamingResources节点下添加如下内容: ```xml <Resource name="jdbc/mydatasource" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" username="root" password="password" maxTotal="20" maxIdle="10" maxWaitMillis="10000"/> ``` 其中,name属性指定了JNDI数据源的名称,url指定了JDBC连接URL,username和password是数据库的用户名和密码,其他属性是为连接池设置的。这里使用的是MySQL数据库作为例子。 2. 重启Tomcat服务器,应用程序将能够通过JNDI查找到配置的数据源,并连接到数据库。 通过上述方法,我们就可以在Spring Boot应用程序中使用JNDI数据源了,同时也可以添加多个数据源,只需要按照上述步骤配置即可。 ### 回答3: SpringBoot是一个开箱即用的框架,可以轻松帮助我们快速搭建JavaWeb应用程序。而JNDI数据源的配置则是在应用程序中连接数据库时必不可少的一步。在SpringBoot中,我们可以使用Tomcat-jdbc来实现JNDI数据源的配置。 以下是具体的步骤: 1. 在maven中引入Tomcat-jdbc的依赖。 ``` <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>${tomcat-jdbc.version}</version> </dependency> ``` 2. 在application.properties文件中定义数据源的配置信息。 ``` # tomcat datasource spring.datasource.jndi-name=jdbc/myDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=mysql spring.datasource.test-on-borrow=true spring.datasource.test-while-idle=true spring.datasource.validation-query=SELECT 1 ``` 这里我们通过配置spring.datasource.jndi-name=jdbc/myDataSource来指定数据源的JNDI名称为“jdbc/myDataSource”。其他配置信息包括驱动程序类名、URL、用户名和密码等都与普通的数据源配置一致。 3. 在application.properties文件中定义JNDI的配置信息。 ``` # JNDI datasource spring.jndi.enabled=true spring.jndi.name=jdbc/myDataSource ``` 这里我们通过配置spring.jndi.enabled=true和spring.jndi.name=jdbc/myDataSource来启用并指定JNDI的配置信息。 4. 在Tomcat中配置数据源。 在应用程序部署到Tomcat中之后,我们还需要在Tomcat中配置数据源。我们可以在Tomcat的server.xml文件中添加以下配置: ``` <GlobalNamingResources> <Resource name="jdbc/myDataSource" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="root" password="mysql" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/test" validationQuery="SELECT 1" /> </GlobalNamingResources> ``` 这里我们通过添加Resource元素来定义数据源,其中name属性的值与application.properties文件中定义的JNDI名称相同。 至此,我们就成功地配置了JNDI数据源。在应用程序中可以通过@Resource注解来引用它: ``` @Resource(lookup="java:comp/env/jdbc/myDataSource") private DataSource dataSource; ``` 除了Tomcat-jdbc,其他的JNDI数据源也可以使用相同的方法来配置。如果我们不想使用JNDI数据源,也可以直接在application.properties文件中配置普通的数据源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值