在Spring Boot中自动装配参数化构造函数 [英] Autowire a parameterized constructor in 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屋!