I am trying to use Spring with Scala. I know Autowired works with Scala class, but I am using a web-framework that requires an object and I want to inject a dao into it. I wonder how to do this? Sorry, I am quite new to Scala, thanks in advance.
@Service
object UserRest extends RestHelper {
@Autowired
@BeanProperty
val userRepository: UserRepository = null;
.....
}
<beans>
.....
<bean id="userRest" class="com.abc.rest.UserRest" >
<!--- this is my attempt to manually wire it --->
<property name="userRepository" ref="userRepository"/>
</bean>
</beans>
Since Spring is the most popular DI and IOC container for Java application, @Autowired is more common and @Inject is lesser-known, but from a portability point of view, it's better to use @Inject. Spring 3.0 supports JSR-330 annotation, so if you are using Spring 3.0 or higher release, prefer @Inject over @Autowired.
Is @Autowired annotation mandatory for a constructor? No. After Spring 4.3 If your class has only single constructor then there is no need to put @Autowired .
Application classWe can use Java/Spring annotations like @SpringBootApplication in Scala the same way as in Java (one exception see below).
So the answer is: No, @Autowired does not necessarily mean you must also use @Component . It may be registered with applicationContext. xml or @Configuration+@Bean .
None of the previous answears worked for me, but after some struggle I could solve it like this:
@Service
class BeanUtil extends ApplicationContextAware {
def setApplicationContext(applicationContext: ApplicationContext): Unit = BeanUtil.context = applicationContext
}
object BeanUtil {
private var context: ApplicationContext = null
def getBean[T](beanClass: Class[T]): T = context.getBean(beanClass)
}
an then the object:
object MyObject {
val myRepository: MyRepository = BeanUtil.getBean(classOf[MyRepository])
}
Basically, you have two problems:
Property should be mutable, i.e. var
rather than val
All methods of Scala object
are static
, whereas Spring expects instance methods. Actually Scala creates a class with instance methods named UserRest$
behind the scene, and you need to make its singleton instance UserRest$.MODULE$
available to Spring.
Spring can apply configuration to preexisting singleton instances, but they should be returned by a method, whereas UserRest$.MODULE$
is a field. Thus, you need to create a method to return it.
So, something like this should work:
object UserRest extends RestHelper {
@BeanProperty
var userRepository: UserRepository = null;
def getInstance() = this
...
}
.
<bean id="userRest"
class="com.abc.rest.UserRest"
factory-method = "getInstance">
<property name="userRepository" ref="userRepository"/>
</bean>
You can replace <property>
with @Autowired
, but cannot replace manual bean declaration with @Service
due to problems with singleton instance described above.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With