Home > Blockchain >  Why Spring @Autowired doesn't work in abstract class?
Why Spring @Autowired doesn't work in abstract class?

Time:03-31

I am doing this way in abstract class

@Autowired
lateinit var fileContract: FileContract

with error

kotlin.UninitializedPropertyAccessException: lateinit property fileContract has not been initialized

But the same works in regular class. Why? How to make autowire in abstract class? whole class https://gist.github.com/iva-nova-e-katerina/ac4fd61d3735ce90935ff09559053f1c

UPD Also I have tried this way https://gist.github.com/iva-nova-e-katerina/358947aa94987138bc4c73178f7b3ae5 but fields are still = null

CodePudding user response:

Because you cannot create an instance/bean for abstract class. It's "abstract".

You can't have an instance/bean, so you cannot wire anything to the instance. That's it.

I believe you will get something like "no unique bean is defined." if you do so.

CodePudding user response:

You should use constructor injection and not field injection where possible. That also would solve your problem, because you do not need to autowire anything in your abstract class, but you just declare it as a constructor parameter:

abstract class AbstractExtractor(
    val fileContract: FileContract,
    val dictionaryContractImpl: DictionaryContractImpl,
    val regulationContractImpl: RegulationContractImpl
) {
 ...
}

Note that the above notation declares fileContract, dictionaryContractImpl and regulationContractImpl as constructor parameters, and at the same time (due to the val keyword) as a local property of the class AbstractExtractor. This means that it is not necessary to declare any additional variables for them inside the class.

Now, your subclass RegulationExtractor also needs to use constructor injection, so that it can pass the autowired values on to the constructor of the super class:

@Service
class RegulationExtractor(
    fileContract: FileContract,
    dictionaryContractImpl: DictionaryContractImpl,
    regulationContractImpl: RegulationContractImpl
) : AbstractExtractor(
    fileContract, 
    dictionaryContractImpl, 
    regulationContractImpl
) {
    ...
}

If you need any of the constructor parameters also in the RegulationExtractor class, you can add the val keyword like in AbstractExtractor.

It should not be necessary to add the @Autowired annotation here, but if you want, you can change the above code to

@Service
class RegulationExtractor @Autowired constructor(
...
  • Related