I have a configuration class with this constructor:
public CxfConfigurerImpl(@Value("${cxfclient.timeout.connection}") long connectionTimeout,
@Value("${cxfclient.timeout.connection-request}") long connectionRequestTimeout,
@Value("${cxfclient.timeout.receive}") long receiveTimeout) {
this.receiveTimeout = receiveTimeout;
this.connectionTimeout = connectionTimeout;
this.connectionRequestTimeout = connectionRequestTimeout;
}
But I have different values to set according with my endpoints requests. Ex:
@Value("${cxfclient.timeout-three.connection}")
private long connectionTimeout3;
@Value("${cxfclient.timeout-three.connection-request}")
private long connectionRequestTimeout3;
@Value("${cxfclient.timeout-three.receive}")
private long receiveTimeout3;
@Autowired
private CxfConfigurerImpl cxfConfigurer3Seg = new CxfConfigurerImpl(connectionTimeout3, connectionRequestTimeout3, receiveTimeout3);
My environment variables are:
CXFCLIENT_TIMEOUT_CONNECTION=1000
CXFCLIENT_TIMEOUT_CONNECTIONREQUEST=1000
CXFCLIENT_TIMEOUT_RECEIVE=1000
CXFCLIENT_TIMEOUTTHREE_CONNECTION=3000
CXFCLIENT_TIMEOUTTHREE_CONNECTIONREQUEST=3000
CXFCLIENT_TIMEOUTTHREE_RECEIVE=3000
The problem is that for the object "cxfConfigurer3Seg" I'm getting the default constructor values (1000). Is there any way to override the values?
OBS: I can't change the "CxfConfigurerImpl" constructor implementation.
CodePudding user response:
Please notes that
@Value : by definition is an Annotation used at the field or method/constructor parameter levelthat indicates a default value expression for the annotated element.
And Note that actual processing of the @Value annotation is performedby a BeanPostProcessor
So values are setted after bean built, otherwise you will already find the value 1000 in your variables
So you should change your implementation here :
You should init configuration in the application level and use @Qualifier for two different bean instead the @Value constructor injection:
@Component
@Getter
@Setter
@ToString
public class B {
private long receiveTimeout;
private long connectionTimeout;
private long connectionRequestTimeout;
public B () {
}
public B ( long connectionTimeout,
long connectionRequestTimeout,
long receiveTimeout) {
this.receiveTimeout = receiveTimeout;
this.connectionTimeout = connectionTimeout;
this.connectionRequestTimeout =
connectionRequestTimeout;
}
}
In the spring boot application startup class : build two beans with two configurations : (b1, b2)
@Value("${cxfclient.timeout-three.connection}")
private long connectionTimeout3;
@Value("${cxfclient.timeout-three.connection-request}")
private long connectionRequestTimeout3;
@Value("${cxfclient.timeout-three.receive}")
private long receiveTimeout3;
@Value("${cxfclient.timeout.connection}")
private long receiveTimeout;
@Value("${cxfclient.timeout.connection-request}")
private long connectionTimeout;
@Value("${cxfclient.timeout.receive}")
private long connectionRequestTimeout;
@Bean ("b1")
public B createAsB1() {
return new B (connectionTimeout3, connectionRequestTimeout3, receiveTimeout3);
}
@Bean ("b2")
public B createAsB2() {
return new B(connectionTimeout, connectionRequestTimeout, receiveTimeout);
}
use them by :
@Component
@Getter
@Setter
@ToString
public class UseB {
@Autowired
@Qualifier ("b1")
private B b1;
@Autowired
@Qualifier ("b2")
private B b2;
}
String d = ab.getB1().toString();
System.out.println(d);
d = ab.getB2().toString();
System.out.println(d);
result of run :
B(receiveTimeout=3000, connectionTimeout=3000,
connectionRequestTimeout=3000)
B(receiveTimeout=1000, connectionTimeout=1000,
connectionRequestTimeout=1000)
CodePudding user response:
There are two options -
1- if you want both the beans available in your application context then you can create two separate beans with two different values.
2- If you want to have both values in your application but only one active bean at a time then you can use @ConditionalOnBean, attaching [here][1] a document for your help. Below is sample rough conditionalonbean code snippet and can enable only one of bean from your configurations file.
@ConditionalOnBean(
"prefix" = "..",
"havingValue" = "true",
"name" = "abc")
public A methodA() {}
@ConditionalOnBean(
"prefix" = "..",
"havingValue" = "false",
"name" = "abc")
public A methodB() {}