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?

Upvotes: 1

Views: 2612

Answers (2)

Kai
Kai

Reputation: 2205

Have you tried adding @Component annotation to the abstract class that had the uninitialized field? We run into a similar problem, that sorted it for us.

Upvotes: 4

Karsten Gabriel
Karsten Gabriel

Reputation: 3662

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

Upvotes: 0

Related Questions