-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Description
Affects: 5.1.6.RELEASE, similar problem appeared trying with spring boot 2.3.2.RELEASE and 1.5.22.RELEASE
Trying to create a way to use Strategy Pattern in my service I constructed this set of classes:
MathOperProcessor is the base class for
- MathOperAdd
- MathOperDivide
- MathOperMultiply
Each of them have a different set of Services @Autowired with setter injection.
And to use them as a service an Enum/@Configuration/@service classes whose snippets are shown below (real implementation can be found in my github project strategy-calculator branch minimum).
public enum MathOperEnum {
// 2 parameters
// 1 - A key to recognize the operation
// 2 - An implementation of MathOperProcessor abstract class
// each implementation has a different set of @Autowired setters.
ADD("add", MathOperAdd.class),
MULTIPLY("mult", MathOperMultiply.class),
DIVIDE("div", MathOperDivide.class);
public String getKey() {
return this.key;
}
public Class<? extends MathOperProcessor> getProcessorClass() {
return this.processorClass;
}
}
@Configuration
public class SpringConfiguration {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MathOperProcessor getMathProcessor(final MathOperEnum mathOper) throws Exception {
return mathOper.getProcessorClass().getConstructor(String.class, long.class)
.newInstance("user", 101L);
}
.....
@Service
public class MathOperService {
@Autowired
ObjectProvider<MathOperProcessor> provider;
public BigDecimal mathOperation( final MathOperEnum operation
, final BigDecimal x
, final BigDecimal y
) {
return this.provider.getObject(operation).execute(x, y);
}
If I call MathOperService.mathOperation(...)
from multiple threads at the same time, @Autowired services with setter injection in MathOperProcessor
implementations do not get populated, in fact some setters are not called while others do, randomly I should say.
A couple of interesting things I found:
- If I call the ObjectProvider from within a synchronized method (MathOperStragetyFactory) in my github project
everything works ok. - Once the error start to occur, next calls to obtain new beans fail to populate @Autowired setters even if called
synchronized. - I tried to get the Beans once and then run the multithread test hoping a kind of cache will fix
the error, but it didn't, which make myself asked, shouldn't Spring annotations for given class be cached ? (Just a doubt).
Finally I tried to search information to see if I was missing some "restrictions" on constructing beans the way I do in @configuration, and wasn't able to find anything discouraging my approach, or doing a similar thing.
1st. issue report sorry if some info is missing
Thanks.