@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();
}
In the above code is there a way that I can access the test/value from a bean (Just as Datasource Bean Works) ???
I have tried many approaches but nothing seems to work. I am able to access the test/value from a controller using ( new InitialContext().lookup("java:comp/env/test/value")
).
There is a way to access test/value
... Because you're initialising your embedded Tomcat container within the Spring context, you have to delay the initialisation of your InitialContext
(until the env vars have been setup).
To achieve this, I used Spring's @Lazy
annotation. e.g.
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();
}
Not sure if this violates any "best practices" - perhaps Spring has a better way of retrieving JNDI variables?? Not sure what the implications are if the JNDI var is changed on the server side (whether the value is re-looked-up)?? If anyone knows, please post back here!
来源:https://stackoverflow.com/questions/36664417/spring-boot-jndi-value-lookup