简体   繁体   English

带有可选嵌入式Tomcat容器的Spring Boot中的JNDI

[英]JNDI in Spring Boot with optional Embedded Tomcat Container

I am rather new to spring boot and have implemented a way of placing a datasource in JNDI context by following the advice given in How to create JNDI context in Spring Boot with Embedded Tomcat Container 我对Spring Boot相当陌生,并已遵循如何在带有嵌入式Tomcat容器的Spring Boot中创建JNDI上下文中给出的建议,实现了一种在JNDI上下文中放置数据源的方法。

I got it to work by adding these beans to the application, which enable naming and place the datasource in JNDI-context like this: 我通过将这些bean添加到应用程序中来使其工作,从而启用命名并将数据源放置在JNDI上下文中,如下所示:

@Autowired
Environment env;

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


@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory(){

  @Override
  public TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(final Tomcat tomcat) {
    tomcat.enableNaming();
    return super.getTomcatEmbeddedServletContainer(tomcat);
  }

  @Override
  public void postProcessContext(final Context context) {
    final String dataSourceURL = env.getProperty("datasource.url");
    // more properties

    final ContextResource resource = new ContextResource();
    resource.setType(DataSource.class.getName());
    resource.setProperty("url", dataSourceURL);
    // more properties

    resource.setName("jdbc/myDB");
    resource.setAuth("Container");
    resource.setType("javax.sql.DataSource");
    resource.setScope("Sharable");

    resource.setProperty("factory", "org.apache.commons.dbcp.BasicDataSourceFactory");

    context.getNamingResources().addResource(resource);
  }
};
}

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

So far so good, it worked. 到目前为止,一切顺利。 But now the specification of the project has changed. 但是现在该项目的规范已更改。 In addition of delivering a fat JAR that starts up an embedded Tomcat (as initially planned), I need to be able to deliver a WAR that has no references to the embedded Tomcat. 除了提供启动嵌入式Tomcat的胖JAR(按最初计划)之外,我还需要能够提供没有对嵌入式Tomcat的引用的WAR。 So i created extra projects for packaging and handled the optional inclusion of embedded Tomcat via Maven dependencies. 因此,我创建了用于打包的其他项目,并通过Maven依赖项处理了嵌入式Tomcat的可选包含。 Problem is, I had to move the code that is shown above out of my main class and into a seperate package which i include via Maven dependency. 问题是,我不得不将上面显示的代码移出我的主类,并移到一个单独的程序包中,该程序包是通过Maven依赖项包含的。 And now it no longer does the trick. 现在,它不再有用。

I admit that I am not too familiar with how the Spring-magic with @Autowired and @Bean works, so I am kind off stumbling around here. 我承认我对@Autowired和@Bean的Spring-magic的工作方式不太熟悉,所以我在这里徘徊了一点。

What do i have to do to make the creation of JNDI context work outside of my main class? 为了使JNDI上下文的创建在主类之外起作用,我该怎么做?

The solution turned out to be quite simple and i could find it by learning more about spring beans. 事实证明,该解决方案非常简单,我可以通过学习更多有关春豆的知识来找到它。 I created another class in which the beans were created, annotated it with @Configuration and added it to the @ComponentScan specification of the main class. 我创建了另一个创建bean的类,并用@Configuration对其进行注释,并将其添加到主类的@ComponentScan规范中。 Looks like this: 看起来像这样:

@ComponentScan(basePackages = {"myBasePackage",
                           "externalPackageContainingConfiguration"})

externalPackageContainingConfiguration is only found when it´s artifact is added via Maven Dependency. 仅当通过Maven依赖关系添加工件时,才找到externalPackageContainingConfiguration A little hacky, but does the trick. 有点骇人听闻,但能解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM