Java Bean创建顺序WebMVCConfigureAdapter Spring

Java Bean创建顺序WebMVCConfigureAdapter Spring,java,spring,spring-mvc,Java,Spring,Spring Mvc,我在SpringMVC中使用以下代码将xml转换为Java类。谁能告诉我如何设置bean创建的顺序。当我运行以下代码时。JDBCTemplatebean在DataSource bean之前创建,并给出异常,因为DataSource为null package com.outbottle.config; import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; import org.springframework.context.annotati

我在SpringMVC中使用以下代码将xml转换为Java类。谁能告诉我如何设置bean创建的顺序。当我运行以下代码时。JDBCTemplatebean在DataSource bean之前创建,并给出异常,因为DataSource为null

package com.outbottle.config;  

import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.ComponentScan;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;  
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.JstlView;  
import org.springframework.web.servlet.view.UrlBasedViewResolver;  
import org.apache.tomcat.jdbc.pool.DataSource;

@Configuration
@ComponentScan("com.outbottle")
@EnableWebMvc   
public class Config extends WebMvcConfigurerAdapter 
{  
    org.apache.tomcat.jdbc.pool.DataSource dataSource;
    JdbcTemplate jdbcTemplate;

    @Bean  
    public UrlBasedViewResolver setupViewResolver() {  
        UrlBasedViewResolver resolver = new UrlBasedViewResolver();  
        resolver.setPrefix("/WEB-INF/jsp/");  
        resolver.setSuffix(".jsp");  
        resolver.setViewClass(JstlView.class);  
        return resolver;  
    } 

    @Bean  
    public org.apache.tomcat.jdbc.pool.DataSource setDataSource() 
    {  
        dataSource = new DataSource();
        dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        dataSource.setUsername("muhiuddin");
        dataSource.setPassword("muhiuddin");
        dataSource.setUrl("jdbc:oracle:thin:@172.19.0.10:1521:db10g");
        dataSource.setMaxIdle(5);
        dataSource.setInitialSize(5);
        return dataSource;
    }

    @Bean  
    public JdbcTemplate setJdbcTemplate() 
    {  
        jdbcTemplate= new JdbcTemplate();
        // setDataSource(); // if I call this function then every thing is OK.
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }      

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) 
    {
        registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/*");
    }
} 

您可以使用
@DependsOn
注释设置bean创建的顺序

诸如此类:

@Bean
@DependsOn("setDataSource")  
public JdbcTemplate setJdbcTemplate() 
{  
    jdbcTemplate= new JdbcTemplate();
    // setDataSource(); // if I call this function then every thing is OK.
    jdbcTemplate.setDataSource(dataSource);
    return jdbcTemplate;
}      
但您也可以调用方法本身:

@Bean  
public org.apache.tomcat.jdbc.pool.DataSource getDataSource() 
{  
    DataSource dataSource = new DataSource();
    dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
    dataSource.setUsername("muhiuddin");
    dataSource.setPassword("muhiuddin");
    dataSource.setUrl("jdbc:oracle:thin:@172.19.0.10:1521:db10g");
    dataSource.setMaxIdle(5);
    dataSource.setInitialSize(5);
    return dataSource;
}

@Bean  
public JdbcTemplate setJdbcTemplate() 
{  
    jdbcTemplate= new JdbcTemplate();
    // setDataSource(); // if I call this function then every thing is OK.
    jdbcTemplate.setDataSource(getDataSource());
    return jdbcTemplate;
}      
TL;DR:永远不要使用实例变量 您的代码应该是:

@Bean  
public javax.sql.DataSource dataSource() 
{  
    final DataSource dataSource = new DataSource();
    dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
    dataSource.setUsername("muhiuddin");
    dataSource.setPassword("muhiuddin");
    dataSource.setUrl("jdbc:oracle:thin:@172.19.0.10:1521:db10g");
    dataSource.setMaxIdle(5);
    dataSource.setInitialSize(5);
    return dataSource;
}

@Bean  
public JdbcTemplate jdbcTemplate(final javax.sql.DataSource dataSource) 
{  
    final JdbcTemplate jdbcTemplate= new JdbcTemplate();
    // setDataSource(); // if I call this function then every thing is OK.
    jdbcTemplate.setDataSource(dataSource);
    return jdbcTemplate;
}      
通过这种方式,Spring知道要创建一个
JdbcTemplate
bean,它需要一个
DataSource
bean;因此,它将正确决定订单

您通过使用实例变量绕过了Spring,Spring无法确定实例的创建时间


还有两件事:

  • @Bean
    方法的名称设置Bean名称,您真的想要一个名为
    setDataSource
    DataSource
    Bean吗
  • bean应该返回
    接口
    抽象类
    ,而不是特定类型,这是为了鼓励通过
    接口
    进行自动连接

  • 这是一个有点黑客绕过滥用
    @Configuration
    。看看我的答案。谢谢你的回复。你能解释一下“TL;DR:永远不要使用实例变量”是什么意思吗。先谢谢你。;永远不要使用实例变量@穆希乌丁