Reputation: 382
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
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
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