问题
@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") ).
回答1:
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