如何在使用弹簧自动布线时传递构造函数参数?
问题描述:
我们的项目使用弹簧DI/IoC,所以我使用自动装配来注入豆类。该程序需要在实例化过程中将参数传递给对象。参数在运行时已知(不在编译时)。如何在使用弹簧自动布线时传递构造函数参数?
如何在使用自动装配时实现此目的。示例代码如下。
接口 - 即时聊天
package com.example.demo.services;
public interface IMessage {
String message(String name);
}
实现 -
SayHelloService
package com.example.demo.services;
import org.springframework.stereotype.Service;
@Service
public class SayHelloService implements IMessage {
String id;
public SayHelloService(String id) {
super();
this.id = id;
}
@Override
public String message(String name) {
return "Hello Dear User - " + name + ". Greeter Id: " + id ;
}
}
MasterService
package com.example.demo.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class MasterService implements IMessage {
String creationTime;
MasterService() {
System.out.println("ms... default constructor");
creationTime = Long.toString(System.currentTimeMillis());
}
//classic java way of creating service
IMessage sayHelloServiceClassicWay = new SayHelloService(creationTime);
//how to achieve above using spring auto wiring. Below code does not exactly do same.
@Autowired
@Qualifier("sayHelloService")
IMessage sayHelloServiceAutoWired;
@Override
public String message(String name) {
return name.toString();
}
}
现在,在上述程序(在MasterService)如何更换
即时聊天sayHelloServiceClassicWay =新SayHelloService(创建时间);
带有弹簧等效代码。
答
它的工作方式不同,在构造函数参数的Spring上下文中创建SayHelloService,然后Spring将自动装入它。无XML congif例如:
class B1 {
@Autowired
B2 b2;
}
class B2 {
B2(int i) {
}
}
@Configuration
class Config {
@Bean
B1 b1() {
return new B1();
}
@Bean
B2 b2() {
return new B2(1);
}
}
在这个例子中,Spring将自动装配B2其中有一个ARG
答
Spring不会以这种方式工作的构造。
您的两个bean在执行和实例化方面过于耦合:第一个bean在构建时创建,第二个在运行时在参数构造函数中传递给它一个生成值。
即使通过依赖注入顺序(@DependsOn
,@Order
或两个@Configuration
哪一个取决于其他的)它不会解决,因为运行时生成的值不是依赖你的问题,玩。
作为一种变通方法,提供了一个方法,以重视在IMessage
接口一旦creationTime
可能是可接受的。 SayHelloService
可能看起来像:
package com.example.demo.services;
import org.springframework.stereotype.Service;
@Service
public class SayHelloService implements IMessage {
String id;
public SayHelloService(String id) {
super();
this.id = id;
}
@Override
public void setId(String id){
// you can add this check to enforce the immutability of id
if (this.id != null){//exception handling}
this.id = id;
}
@Override
public String message(String name) {
return "Hello Dear User - " + name + ". Greeter Id: " + id ;
}
}
而且你可以用这种方式改变MasterService
:
private IMessage sayHelloServiceAutoWired;
@Autowired
MasterService(@Qualifier("sayHelloService")
IMessage sayHelloServiceAutoWired) {
System.out.println("ms... default constructor");
creationTime = Long.toString(System.currentTimeMillis());
this.sayHelloServiceAutoWired = sayHelloServiceAutoWired;
this.sayHelloServiceAutoWired.setId(creationTime);
}
PS:自动装配构造不是强制性的,但它是清洁剂没有API来设置的依赖性班上。你也可以使用setter。
为变量创建一个getter和setter,然后在autowired字段上使用setter方法。 – user641887
在您的配置xml中,将SayHelloService的bean中的“creationTime”属性指定为constructor-arg。 Spring将自动装入它。 – Coder
@ user641887,你可以添加一些代码PLZ。 – samshers