如何在 Scala 对象中使用 Spring 自动连线(或手动连线)?
我正在尝试将 Spring 与 Scala 一起使用。我知道 Autowired 可与 Scala 类一起使用,但我使用的 Web 框架需要一个对象,并且我想向其中注入一个 dao。我想知道如何做到这一点?抱歉,我对 Scala 还很陌生,提前致谢。
@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>
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
基本上,您有两个问题:
属性应该是可变的,即
var
而不是val
Scala
object
的所有方法都是static
,而 Spring 需要实例方法。实际上,Scala 在幕后创建了一个名为UserRest$
实例方法的类,您需要使其单例实例UserRest$.MODULE$
对 Spring 可用。Spring 可以将配置应用于预先存在的单例实例,但它们应该由方法返回,而 UserRest$.MODULE$ 是一个字段。因此,您需要创建一个方法来返回它。
所以,像这样的东西应该有效:
.
您可以将
替换为@Autowired
,但由于上述单例实例的问题,无法将手动 bean 声明替换为@Service
。另请参阅:
Basically, you have two problems:
Property should be mutable, i.e.
var
rather thanval
All methods of Scala
object
arestatic
, whereas Spring expects instance methods. Actually Scala creates a class with instance methods namedUserRest$
behind the scene, and you need to make its singleton instanceUserRest$.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:
.
You can replace
<property>
with@Autowired
, but cannot replace manual bean declaration with@Service
due to problems with singleton instance described above.See also:
实际上所需要的只是将对象定义为类,而不是对象。这样Spring就会实例化它。
将“val”更改为“var”是不必要的(Spring 使用反射,它忽略了不变性)。我很确定 @BeanProperty 也是不必要的(Spring 将反射地分配给底层字段)。
All that's actually necessary is that you define your object as a class, rather than an object. That way Spring will instantiate it.
Changing the "val" to "var" is unnecessary (Spring uses reflection, which ignores immutability). I'm pretty sure that that @BeanProperty is also unnecessary (Spring will assign to the underlying field, reflectively).
axtavt 的解决方案对我来说不起作用,但是结合其他答案的不同建议,我认为这是最优雅的解决方案:
一些注意事项:
axtavt's solution did not work for me, but combining different suggestions from the other answers I think this is the most elegant solution:
A few notes:
我所做的是使用 AutowiredAnnotationBeanPostProcessor 在构造时注入对象。
例如:
现在你可以使用AppConfig.inject()来注入任何生命周期不受Spring控制的对象。例如,JPA 实体等。
What I do is use AutowiredAnnotationBeanPostProcessor to inject the object at construction time.
For example:
Now you can use AppConfig.inject() to inject any object whose lifecycle is not controlled by Spring. For example, JPA Entities, etc.
使用 @Component 或 @Bean 标记的类中的普通 Autowire 将按照上述方式工作。
但是,如果您想自动连接扩展 Jpa 存储库的接口,请确保 Dao 不是对象而是类。
例如:
DAO:
这行不通(已测试)。我的猜测是,由于它被定义为一个对象,因此在运行时使用 repo 作为 null 值进行实例化,因此无法自动装配 jpa repo。
相反,将其声明为类并使用 @Component 进行标记:
它可以工作,因为我们让 spring 来管理正确自动装配 jpa 存储库的对象创建(@component)。
Normal Autowire from a class that is marked with @Component or @Bean would work with above mentioned ways.
But if you want to auto wire an interface extending Jpa repository then make sure the Dao is not an object but class.
ex:
DAO:
This won't work (tested). My guess is that since it's defined as an object, gets instantiated at run time with repo as null value, hence won't be able to autowire jpa repo.
Instead declare it as class and mark with @Component:
It works since we are letting spring to manage the object creation(@component) that autowires jpa repo properly.
之前的答案都不适合我,但经过一番努力,我可以像这样解决它:
然后是对象:
None of the previous answears worked for me, but after some struggle I could solve it like this:
an then the object:
除了 https://stackoverflow.com/a/8344485/5479289 之外,还可以添加 scala 使用工厂方法将对象打包到 Spring 上下文,以及 scala 对象。编译后的包对象是名为package的常见java类,因此您可以将其添加到Spring上下文中。之后,您将在该对象中拥有 Spring 的所有可能性,即 @Autowired、@Value、手动接线等。
测试包:
Spring 上下文 xml 是:
In addition to https://stackoverflow.com/a/8344485/5479289, it's also possible to add scala package object to Spring context, as well as scala object, using factory method. Compiled package object is usual java class named package, so you can add it to Spring context. After that you will have all Spring's possibilities inside this object, i.e @Autowired, @Value, manual wiring etc.
Test package:
And spring context xml is:
我遇到了同样的问题。
我有很多服务,想从 scala 对象调用这些 @Autowired 服务。
我尝试了以上所有方法,但都没有达到我的预期。
我有一个名为
JobConfig.scala
的对象,我想自动装配TableResolver
类,并且TableResolver
类本身自动装配许多其他类。我的应用程序是在 spring boot 和 scala 中。
XmlBeansConfig.scala
JobConfig.scala
内I faced same issue.
I have many services and want to call these @Autowired service from scala objects.
I tried all the above, None of them worked as my expectation.
I have an object named
JobConfig.scala
and I want to autowireTableResolver
class andTableResolver
class itself autowire many other classes.My application is in spring boot and scala.
src/main/resources/applicationContext.xml
file.XmlBeansConfig.scala
JobConfig.scala