在Spring Boot中自动装配参数化构造函数 [英] Autowire a parameterized constructor in spring boot

查看:1598
本文介绍了在Spring Boot中自动装配参数化构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在参数化构造函数中传递值时,我无法自动装配bean。

I am not able to autowire a bean while passing values in paramterized constructor.

如何使用SpringBoot调用参数化构造函数?

How to call the parameterized constructor using SpringBoot?

@Component
public class MainClass {

    public void someTask() {
        AnotherClass obj = new AnotherClass(1, 2);
    }

}
//Replace the new AnotherClass(1, 2) using Autowire?

@Component
public class AnotherClass {
    private int number,age;

    public AnotherClass(int number, int age) {
        super();
        this.number = number;
        this.age = age;
    }
}

我想自动装配 AnotherClass bean。
如何删除新的 AnotherClass(1,2);
如何放置 @Autowire 在这里?

I want to autowire "AnotherClass" bean. How to remove the new AnotherClass(1, 2); How can I place @Autowire here?

推荐答案

您需要在构造函数中指定此bean:

You need to specify this bean in the constructor:

@Component
public class MainClass {

    private final AnotherClass anotherClass;

    // this annotation is NOT required if there is only 1 constructor, shown for clarity.
    @Autowired
    MainClass(AnotherClass anotherClass) {
        this.anotherClass = anotherClass;
    }
    public void someTask() {
        // anotherClass is already instantiated by the time you get here.
    }

}






选项1:直接允许通过组件扫描创建 AnotherClass


Option 1: Directly allow AnotherClass to be created with a component scan.

现在,为了使Spring能够将 AnotherClass 构造为bean,您需要以 Spring方式告诉它从何处获取其值:

Now, in order for Spring to be able to construct AnotherClass as a bean, you need to tell it in a 'Spring way' about where it gets it's values from:

@Component
public class AnotherClass {
    private final int number,age;

    // also not needed if this is the only constructor.
    @Autowired
    public AnotherClass(
// @Value is a spring annotation to provide spring the value it needs for this parameter.
                        @Value("${property.number:0}") int number, 
                        @Value("${property.age:0}") int age) {
        this.number = number;
        this.age = age;
    }
}

这是在拉2个属性, code> property.number 和 property.age from application.properties | application.yml 表示这些整数的值。

What this is doing, is pulling 2 properties, property.number and property.age from application.properties|application.yml for the value(s) of those integers.

您需要确保这两个类位于组件扫描路径上,否则spring boot不会尝试制作这些类的bean。

You will need to ensure both of these classes are on the component scan path, or else spring boot won't attempt to make beans of these classes.

选项2:使用配置类制作 AnotherClass bean

Option 2: Use a Configuration Class to make the AnotherClass bean

@Configuration
public class MyConfigurationClass {

    @Bean
    public AnotherClass anotherClass {
        return new AnotherClass(1,2)
    }
}

在此示例中,您不会 @Component 注释 AnotherClass

In this example, you would not annotate AnotherClass with @Component.

选项3:使用自定义工厂方法找到在此博客中

Option 3: Use a custom factory method as found in this blog.

再次使用此策略, 请勿 注释另一个类 @Component

Again, with this strategy, do not annotate AnotherClass with @Component

@Configuration
public class MyConfigurationClass {

    @Bean
    public BiFunction<Integer, Integer, MyPrototype> myPrototypeFactory() {
        return start, age -> anotherClass(start, age);
    }

    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public AnotherClass anotherClass(Integer start, Integer age) {
        if (start == null || age == null) {
            throw new IllegalArgumentException("start was: " + start + ", age was: " + age + ". Neither can be null!");
        }
        return new AnotherClass(start,age);
    }
}

用法:

@Component
public class MainClass {

    private final BiFunction<Integer, Integer, AnotherClass> anotherClassFactory;

    // this annotation is NOT required if there is only 1 constructor, shown for clarity.
    @Autowired
    MainClass(BiFunction<Integer, Integer, AnotherClass> anotherClassFactory) {
        this.anotherClassFactory = anotherClassFactory;
    }
    public void someTask() {
        AnotherClass ac = anotherClassFactory.apply(1,2);
        // do something with your new AnotherClass
    }

}






选项4:使用 ObjectProvider (自Spring 4.3起)在此博客帖子中找到


Option 4: Use ObjectProvider (Since Spring 4.3) as found in this blog post.

同样,使用此策略, 不要 注释 AnotherClass @Component

Again, with this strategy, do not annotate AnotherClass with @Component

@Configuration
public class MyConfiguration {
    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public AnotherClass createAnotherClass(Integer start, Integer age) {
        return new AnotherClass(start, age);
    }
}

用法:

@Component
public class MainClass {

    private final ObjectProvider<AnotherClass> anotherClassProvider;

    // this annotation is NOT required if there is only 1 constructor, shown for clarity.
    @Autowired
    MainClass(ObjectProvider<AnotherClass> anotherClassProvider) {
        this.anotherClassProvider = anotherClassProvider;
    }
    public void someTask() {
        // may need to cast the result of '.getObject()'
        AnotherClass ac = anotherClassProvider.getObject(/*start*/ 1, /*age*/ 2);
        // do something with your new AnotherClass
    }

}

这篇关于在Spring Boot中自动装配参数化构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆