2016-04-16 1 views
1
@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(); 
    } 

В приведенном выше коде есть способ, что я могу получить доступ к тест/значение из фасоли (как DataSource Bean Works) ???Spring Boot - JNDI значение поиска

Я пробовал много подходов, но ничего не работает. Я могу получить доступ к тесту/значению с контроллера (new InitialContext().lookup("java:comp/env/test/value")).

+0

Почему вы даже хотите использовать JNDI. Что это такое, вы используете встроенный контейнер, так что вы можете добиться того же, что и объявление источника как простой компонент, а не JNDI. ИМХО, вы делаете вещи более сложными, чем необходимо. –

ответ

0

Существует способ доступа к test/value ... Поскольку вы инициализируете встроенный контейнер Tomcat в контексте Spring, вам необходимо отложить инициализацию вашего InitialContext (пока не были установлены настройки env vars).

Для этого я использовал аннотацию весны @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 изменена на стороне сервера (независимо от того, пересчитывается ли значение)? Если кто знает, пожалуйста, напишите здесь!