Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Spring Autowired (or manually wired) in Scala object?

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>
like image 800
bernardw Avatar asked Dec 01 '11 15:12

bernardw


People also ask

Should I use Autowired or inject?

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 mandatory in Spring boot?

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 .

Can you use Spring with Scala?

Application classWe can use Java/Spring annotations like @SpringBootApplication in Scala the same way as in Java (one exception see below).

Can we use @autowired without @component?

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 .


2 Answers

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])
}
like image 165
Caio Duarte Avatar answered Nov 16 '22 01:11

Caio Duarte


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:

  • What is the Java equivalent of a Scala object?
  • 3.3.2.2 Instantiation with a static factory method
like image 32
axtavt Avatar answered Nov 16 '22 03:11

axtavt