Java 如何使用参数创建Springbean(数据源)?

Java 如何使用参数创建Springbean(数据源)?,java,spring,Java,Spring,同事们,我是春天四号的新人。 我有一个调用过程的类: public class ProductDAOImpl implements ProductDAO { public Product getProductUsingProc(int PassID, int Amount) { SqlParameterSource sqlParameterSource = new MapSqlParameterSource().addValue("PassID", PassID).a

同事们,我是春天四号的新人。 我有一个调用过程的类:

public class ProductDAOImpl implements ProductDAO  {

  public Product getProductUsingProc(int PassID, int Amount) {


        SqlParameterSource sqlParameterSource = new MapSqlParameterSource().addValue("PassID", PassID).addValue("Amount", Amount);
         WebServiceConfig wsc = new WebServiceConfig();

        DataSource dataSource = wsc.DataSource("DB1"); 
        SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource).withProcedureName("PRODUCT_CREATE");

        Map<String, Object> result = simpleJdbcCall.execute(sqlParameterSource);

        Product product = new Product();

        product.setPassID(PassID); 
        product.setAmount(Amount);
        product.setReturnValue( (int) result.get("ReturnValue") );
        product.setProductID((int) result.get("ProductID"));

        return product;
    }
但当运行程序时,我会收到下一个堆栈跟踪:

Error starting ApplicationContext. To display the auto-configuration report enable debug logging (start with --debug)


ERROR: [oct-26 16:46:44,337] springframework.boot.SpringApplication - Application startup failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'DataSource' defined in class path resource [com/mayacomp/service/app/WebServiceConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang. String]: : No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for  this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Depende ncy annotations: {}
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBean Factory.java:1119)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.jav a:1014)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)

        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
        at com.mayacomp.service.app.WsApplication.main(WsApplication.java:12) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency: e xpected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.jav a:1301)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
        ... 18 more Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'DataSource' defined i n class path resource [com/mayacomp/service/app/WebServiceConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: : No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifie s as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefiniti onException: No qualifying bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate f or this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBean Factory.java:1119)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.jav a:1014)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)

        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
        at com.mayacomp.service.app.WsApplication.main(WsApplication.java:12) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency: e xpected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.jav a:1301)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
        ... 18 more
当我使用没有“字符串源”的bean时,它可以正常工作吗

更新

我通过对每个数据源使用单独的bean解决了这个问题:

@Bean
    @Primary
    @ConfigurationProperties(prefix="datasource.primary")
        public BasicDataSource DataSource() {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            dataSource.setUrl("jdbc:sqlserver://");
            dataSource.setUsername("user");
            dataSource.setPassword("pass");
            dataSource.setMaxIdle(10);
            dataSource.setMaxWaitMillis(10000);
            dataSource.setValidationQuery("select 1");
            dataSource.setTestOnBorrow(false);
            dataSource.setTestWhileIdle(true);
            dataSource.setDefaultAutoCommit(true);
            return dataSource;
        }

    @Bean
    @ConfigurationProperties(prefix="datasource.secondary")
    public BasicDataSource DataSource1() {
        BasicDataSource DataSource1 = new BasicDataSource();
        DataSource1.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        DataSource1.setUrl("jdbc:sqlserver://");
        DataSource1.setUsername("user");
        DataSource1.setPassword("pass");
        DataSource1.setMaxIdle(10);
        DataSource1.setMaxWaitMillis(10000);
        DataSource1.setValidationQuery("select 1");
        DataSource1.setTestOnBorrow(false);
        DataSource1.setTestWhileIdle(true);
        DataSource1.setDefaultAutoCommit(true);
        return DataSource1;
    }


    @Bean
    @ConfigurationProperties(prefix="datasource.secondary")
    public BasicDataSource DataSource2() {
        BasicDataSource DataSource2 = new BasicDataSource();
        DataSource2.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        DataSource2.setUrl("jdbc:sqlserver://");
        DataSource2.setUsername("user");
        DataSource2.setPassword("pass");
        DataSource2.setMaxIdle(10);
        DataSource2.setMaxWaitMillis(10000);
        DataSource2.setValidationQuery("select 1");
        DataSource2.setTestOnBorrow(false);
        DataSource2.setTestWhileIdle(true);
        DataSource2.setDefaultAutoCommit(true);
        return DataSource2;
    }

您可以在配置中使用@PropertySource(“yourFile.properties”),并通过如下环境获取属性:

    @Configuration
    @PropertySource("yourFile.properties")
    public class YourConfiguration{

        @Autowired
        Environment env

        @Bean
        public BasicDataSource DataSource() {
         String source = env.getProperty("source");
         //your code below
        }
     }

希望此帮助

当您在带有@Bean注释的方法中传递参数时,每个参数都由spring容器解析,在您的特定情况下,spring无法找到一个string类型的Bean来满足依赖关系,因为您没有设置任何参数(而且您不应该设置!)

如果您想注入一些参数,spring会为您提供@Value注释(这是spring有助于注入属性的几种不同方式之一),例如:

您需要在资源文件夹的application.properties文件中定义属性your.property.name,如下所示

your.property.name=我的值

n、 b


您可以在您的上下文配置文件中使用@PropertySource从您喜欢的任何地方导入属性(我被spring boot宠坏了,以至于忘记了spring是否自动加载属性:D)

source
代表什么。。。为什么是
字符串
源代码是数据库的名称,我将使用输入参数*/添加开关而不是/*一些代码,并将返回指定的数据源以从数据库获取数据。看起来您正在以非常复杂的方式重新发明轮子。Hibernate已经提供了开箱即用的多租户支持,另一个已经有文档记录。这样,您就不需要乱搞数据源了。(也许我应该更新它以显示java配置而不是xml配置)。类似SimpleJDBCall SimpleJDBCall=新SimpleJDBCall(数据源);我想确定datasource是否使用datasource datasource=SpringConfigFile.datasource(“TEST_DB”)这样的代码;不,您不希望这样,因为您不希望每次需要时都创建一个
SimpleJdbcCall
。它构造了一个
jdbc模板
,这是一个相当繁重的操作。您希望透明地执行类似的操作,因此需要切换数据源。我向您指出的解决方案可以在生产中使用大约75种不同的数据源(大约10年了),无论使用何种技术(基本上可以使用您想要的每个bean)。我需要从文件中获取属性,这取决于输入源参数。如果Source=“DB1”,那么我需要为prod DB1获取url,user,pass,如果Source=“DB2”,那么我需要为prod DB2获取url,user,pass。您还可以查看@Profile,它允许您为应用程序定义概要文件(一个用于DB1,一个用于DB2)。如果你只需要Emanuele-Ivaldi的值,这个答案就行了。@value可以和profiles一起使用,profiles可以用来加载不同的属性文件,在spring bootEmanuele-Ivaldi中有一个非常好的方法,非常感谢你的回复。我添加了一个类,它描述了我如何使用数据源。请看。也许这有助于理解我的问题:我想基于输入参数获取数据源。不客气,您可以在上下文中定义任意数量的数据源(所有这些数据源都可以加载我在响应中显示的属性),然后让某种提供程序在运行时基于参数获取它们,如果你真的想这样做。你的意思是我应该用不同的名称和URL/users/pass创建一些不同的数据源(bean)?这确实取决于你的应用程序,但这肯定是一个可行的解决方案。我将尝试在我的spring配置文件中添加一些新的bean,如DataSourceDB1、DataSourceDB2。这将是一个小代码重复,但如果它将工作,我会很高兴。非常感谢。
    @Configuration
    @PropertySource("yourFile.properties")
    public class YourConfiguration{

        @Autowired
        Environment env

        @Bean
        public BasicDataSource DataSource() {
         String source = env.getProperty("source");
         //your code below
        }
     }
public BasicDataSource DataSource(@Value("${your.property.name}") String source)