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

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?



Solution 1:[1]

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.

Solution 2:[2]

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(
...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nnhthuan
Solution 2