简体   繁体   English

春季启动豆订单

[英]Spring boot beans order

i'm trying to configure a spring boot project with a jetty EmbeddedContainerServlet and jndi datasource, the code below 我正在尝试使用码头的EmbeddedContainerServlet和jndi数据源配置一个春季启动项目,下面的代码

@Configuration
public class EmbeddedJettyServer {

  @Value("${jetty.http.port:8080}")
  private Integer port;
  @Value("${jetty.threadPool.maxThreads:200}")
  private String maxThreads;
  @Value("${jetty.threadPool.minThreads:8}")
  private String minThreads;
  @Value("${jetty.threadPool.idleTimeout:60000}")
  private Integer idleTimeout;

private JettyServerCustomizer jettyServerCustomizer() {
    return new JettyServerCustomizer() {

        @Override
        public void customize(Server server) {
            try {
                // Tweak the connection pool used by Jetty to handle
                // incoming HTTP connections
                final QueuedThreadPool threadPool = new QueuedThreadPool();
                threadPool.setMaxThreads(Integer.valueOf(maxThreads));
                threadPool.setMinThreads(Integer.valueOf(minThreads));
                server.getBeans().add(threadPool);
                WebAppContext webAppContext = (WebAppContext) server.getHandler();
                createConfiguration(
                    "/Users/kewnen/git/zeus-info-provider/zeus-info-provider-web/ops/resources/jetty-datasource.xml")
                        .configure(webAppContext);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        private XmlConfiguration createConfiguration(String xml) throws IOException, SAXException {
            return new XmlConfiguration(new FileInputStream(xml));
        }
    };
}

@Bean
public EmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
    final JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory = new JettyEmbeddedServletContainerFactory() {
        @Override
        protected JettyEmbeddedServletContainer getJettyEmbeddedServletContainer(Server server) {
            return new JettyEmbeddedServletContainer(server);
        }
    };
    jettyEmbeddedServletContainerFactory.addServerCustomizers(jettyServerCustomizer());
    jettyEmbeddedServletContainerFactory.setPort(port);
    jettyEmbeddedServletContainerFactory.setSessionTimeout(idleTimeout);
    return jettyEmbeddedServletContainerFactory;
}

} }

The content of jetty-datasource.xml file where i define the datasource stuff 我定义数据源内容的jetty-datasource.xml文件的内容

  <?xml version="1.0"?>
   <Configure class="org.eclipse.jetty.webapp.WebAppContext">
     <Set name="contextPath">/</Set>

      <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">
         <Arg>jdbc/zeus-info</Arg>
         <Arg>
             <New class="org.apache.commons.dbcp.BasicDataSource">
            <Set name="driverClassName">org.postgresql.Driver</Set>
            <Set name="url">jdbc:postgresql://localhost:5433/myDb</Set>
            <Set name="username">postgres</Set>
            <Set name="password">password</Set>
            <Set name="validationQuery">SELECT 1</Set>
        </New>
    </Arg>
</New>

and then i define a datasource with the code below 然后用下面的代码定义一个数据源

@Bean
public DataSource dataSource() {
    JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
    return dsLookup.getDataSource("jdbc/zeus-info");
}

When i run it, i got this exception 当我运行它时,我遇到了这个异常

  Caused by: javax.naming.NameNotFoundException; remaining name 'jdbc/zeus-info'
at     org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:490)
at org.eclipse.jetty.jndi.local.localContextRoot.lookup(localContextRoot.java:536)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:155)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:104)
at org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup.getDataSource(JndiDataSourceLookup.java:45)

when debuggin i see clearly the Datasource bean instantiate before the definition of the JettyEmbeddedServletContainerFactory where i define my jndi datasource, 当调试时,我清楚地看到在定义我的jndi数据源的JettyEmbeddedServletContainerFactory的定义之前,数据源bean实例化了,

i tried to force the order by adding @DependsOn annotation to the datasource definition but doesn't work, it always instantiate the DataSource bean before the container, 我试图通过在数据源定义中添加@DependsOn批注来强制执行该命令,但不起作用,它总是在容器之前实例化DataSource bean,

Edit: 编辑:

to give more details, 提供更多细节,

i already test it by defining datasource without using jndi this way and works fine: 我已经通过不使用jndi的方式定义数据源来对其进行测试,并且可以正常工作:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(DRIVER_CLASS_NAME);
    dataSource.setUrl(URL);
    dataSource.setUsername(USER);
    dataSource.setPassword(PASS);
    return dataSource;
}

but as its a migration from classique war with datasource defined by jndi to spring boot jar packaging project, i want to reproduce the same from existing project, cause i dont know the impact of changing jndi way to this one. 但是随着从jndi定义的数据源的经典之战到spring boot jar包装项目的迁移,我想从现有项目中复制相同内容,因为我不知道将jndi方式更改为此项目的影响。

I tried to force datasource to be instanciated after container by adding this line on datasource definition 我试图通过在数据源定义上添加以下行来强制在容器之后实例化数据源

 @DependsOn("jettyEmbeddedServletContainerFactory")

but always instanciate the Datasource before the jetty container 但总是在码头集装箱之前实例化数据源

Fix : 解决:

the problem was that spring-boot configure automatically a container with this name jettyEmbeddedServletContainerFactory, thats why @DependsOn("jettyEmbeddedServletContainerFactory") didn't work, 问题是spring-boot会自动配置一个名为jettyEmbeddedServletContainerFactory的容器,这就是@DependsOn(“ jettyEmbeddedServletContainerFactory”)无法正常工作的原因,

i add 我加

@EnableAutoConfiguration(exclude = EmbeddedServletContainerAutoConfiguration.class)

to my app and now it works 到我的应用程序,现在可以使用了

appreciate your help! 感谢您的帮助!

You can use Spring Boot properties to initialize data source bean instead of JNDI: 您可以使用Spring Boot属性而不是JNDI来初始化数据源bean:

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.password=password
spring.datasource.type=org.apache.commons.dbcp.BasicDataSource
spring.datasource.url=jdbc:postgresql://localhost:5433/myDb
spring.datasource.username=postgres
spring.datasource.validation-query=SELECT 1

Reaction on comment: 对评论的反应:

So your dev environment should be as close Prod as possible. 因此,您的开发环境应尽可能接近Prod。 Therefore I woudln't use embedded container and rather use standalone one for development. 因此,我不会使用嵌入式容器,而是使用独立的容器进行开发。 For CI build youcan use maven-jetty-plugin or Gradle Jetty plugin 对于CI构建,您可以使用maven-jetty-plugin或Gradle Jetty插件

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

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