【问题标题】:Spring Boot - JNDI value lookupSpring Boot - JNDI 值查找
【发布时间】:2016-04-16 12:51:52
【问题描述】:
@SpringBootApplication
public class SampleTomcatJndiApplication {

    public static void main(String[] args) {
        SpringApplication.run(SampleTomcatJndiApplication.class, args);
    }

    @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("jdbc/myDataSource");
                resource.setType(DataSource.class.getName());
                resource.setProperty("driverClassName", "your.db.Driver");
                resource.setProperty("url", "jdbc:yourDb");

                context.getNamingResources().addResource(resource);

                ContextEnvironment contextEnv = new ContextEnvironment();
                contextEnv.setName("test/value");
                contextEnv.setType("java.lang.String");
                contextEnv.setOverride(false);
                contextEnv.setValue("testing");
                context.getNamingResources().addEnvironment(contextEnv);
            }
        };
    }

    @Bean(destroyMethod="")
    public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
        bean.setJndiName("java:comp/env/jdbc/myDataSource");
        bean.setProxyInterface(DataSource.class);
        bean.setLookupOnStartup(false);
        bean.afterPropertiesSet();
        return (DataSource)bean.getObject();
    }

在上面的代码中,有没有一种方法可以让我从 bean 访问 test/value(就像 Datasource Bean 一样)???

我尝试了很多方法,但似乎没有任何效果。我可以使用(new InitialContext().lookup("java:comp/env/test/value"))从控制器访问测试/值。

【问题讨论】:

  • 为什么还要使用 JNDI。它添加了什么,您使用的是嵌入式容器,因此您可以通过将数据源声明为普通 bean 而不是 JNDI 来实现相同的目的。恕我直言,您正在使事情变得比需要的更复杂。

标签: java spring spring-boot jndi lookup


【解决方案1】:

有一种方法可以访问test/value... 因为您是在 Spring 上下文中初始化嵌入式 Tomcat 容器,所以您必须延迟初始化 InitialContext(直到设置了环境变量)。

为了实现这一点,我使用了 Spring 的 @Lazy 注释。例如

SampleTomcatJndiApplication.java

import javax.naming.*;

@Bean
@Lazy
public Context environmentContext() throws NamingException {
    Context ctx = new InitialContext();
    Context envCtx = (Context) ctx.lookup("java:comp/env");
    return envCtx;
}

SomeOtherComponent.java

@Lazy
@Autowired
private Context environmentContext;

public String getTestValue() throws NamingException {
    return environmentContext.lookup("test/value").toString();
}

不确定这是否违反任何“最佳实践”——也许 Spring 有更好的方法来检索 JNDI 变量?不确定如果在服务器端更改 JNDI var 会产生什么影响(是否重新查找该值)?如果有人知道,请回这里!

【讨论】:

    猜你喜欢
    • 2021-05-10
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多