A noob question: When using Spring’s `@Autowired` ...
# spring
j
A noob question: When using Spring’s 
@Autowired
 with Kotlin, I’m confused whether this
Copy code
@Autowired
private lateinit var userService: UserService
is a field injection or a setter injection. In the documentation, the Kotlin equivalent of both field and setter injection of Java were all in this fashion. I read that field injection should be avoided, and I’ll try to stick with constructor injection if possible, but I’m just trying them out to learn. If there is actually like a more stricter equivalents, I’d like to know how to write them in Kotlin. Can anyone shed some light on this to me?
t
that is setter injection and is not the preferred way. a
var
in kotlin generates setter and getter and since your user service is not part of the constructor setter injection will be used
Copy code
@Component
class MyBean(private val userService: UserService)
will use constructor injection (and a final user service). in modern spring, when using constructor injection and there is only one constructor, you don’t even have to use
@Autowired
, that just to show how much constructor injection is preferred
j
As I stated, I read about the constructor injection being preferred and the implicit
@Autowired
for newer Spring versions, it was more of a theoretical question.
Then would this be seen as BOTH field and setter injection when using Kotlin? Or is it only one of the two?
t
field injection happens when the setter is not used. I am not sure how to do it in kotlin honestly. maybe
@field:Autowired
would bypass the setter
afaik, the main point is that in java you declare a variable and then define setter and getter, in kotlin that is done for you based on
val
or
var
. when you do
val
you need to initialize at construction time, so with spring it will always be construction injection. when you do
var
a setter is always (and here is where I am not sure) is always created for you and you can use
lateinit
thus enabling setter injection
👍 1
j
This part of the documentation was what got me confused. https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-autowired-annotation
You can also apply the
@Autowired
annotation to traditional setter methods, as the following example shows:
Copy code
class SimpleMovieLister {

    @Autowired
    lateinit var movieFinder: MovieFinder

    // ...

}
You can apply
@Autowired
to fields as well and even mix it with constructors, as the following example shows:
Copy code
class MovieRecommender @Autowired constructor(
    private val customerPreferenceDao: CustomerPreferenceDao) {

    @Autowired
    private lateinit var movieCatalog: MovieCatalog

    // ...
}
e
note the private in the second example - kotlin doesn’t generate a setter for private vars
t
good catch, I did not see it was
private
. eh eh, sometimes eyes can gloss over words in a pretty significant way. I am anyway cross posting this to the #spring channel, they are mixing public and private fields without a note highlighting the difference and even though in hindsight it is obvious I think one extra line might prevent such confusion in the future
actually we are in the spring channel, early friday morning, apparently am totally awake yet