Skip to content

@Autowired setters not called in PrototypeBeans created in @Configuration #25840

@toniocus

Description

@toniocus

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions