spring/scala:可以自动装配 bean 依赖项吗?

spring/scala:可以自动装配 bean 依赖项吗?

问题描述:

我正在尝试在 spring(在 scala 中)没有 xml 配置的情况下执行以下操作

I'm trying do the following without xml configuration in spring (in scala)

<beans ... >
   ## (1)
   ## Auto create a bean by classname
   ## Auto-wires properties of x.y.Bar
   <bean id="baz" class="x.y.Baz"/>

   ## (2)
   ## Create a x.y.Foo and auto-wire the property
   <bean id="foo" class="x.y.Foo">
      <property name="b" ref="baz"/>
   </bean>
</beans>

我们有:

 class Baz {}

 class Foo {
   @Autowired   //?
   @BeanProperty
   val baz:Baz = null
 }

我有以下测试设置:

 @Configuration
class Config {
  //@Autowired  // Seem not to help
  @Bean //( autowire=Array( classOf[Autowire.BY_TYPE ]) )
  def foo: Foo = null
}

class BeanWithAutowiredPropertiesTest {

  @Test
  @throws[Exception] def beanWithAutowiredPropertiesTest(): Unit = {
    var ctx = new AnnotationConfigApplicationContext(classOf[Config]);
    val foo = ctx.getBean(classOf[Foo])
    assertTrue(foo != null)
    assertTrue(ctx.getBean(classOf[Foo]).baz != null)
  }
}

我了解几个简单的替代方案:

I understand a couple of simple alternatives:

  • @ComponentScan -- 这种方法有几个问题:

  • @ComponentScan -- this approach has several issues:

  • 不精确 - 一个包中可以有许多与自动连接类型匹配的类
  • 它(本身)不允许为属性选择特定值
  • 大型项目的扫描速度非常慢
  • 无法将@Component 添加到 3rd 方类

  • imprecision - there can be many classes matching an auto-wired type in a package
  • it doesn't (in itself) permit selecting specific values for properties
  • scanning is painfully slow for large projects
  • Can't add @Component to 3rd party classes

(如果我可以按名称注册候选自动连线类型,那会有很大帮助!)

(If I could register candidate auto-wire types, by name, that would help a lot!)

.

  @Bean
  def foo:Foo = {
     val f = new Foo()
     f.baz = ?? grrr! where from? Not available in this Config 
     f
  }

然而:

  • 这有点绕开了自动接线的问题.如果我明确选择了要设置的参数 baz,那么我首先需要实际获得对它的引用才能做到这一点.通常这可能很困难,特别是如果要使用的实际 baz 可能在另一个 @Configuration 中指定.

  • this sorta circumvents the point of auto-wiring. If I explicitly chose a parameter, baz to set, then I need to actually get a reference to it to do that in the first place. Frequently this can be difficult, especially if the actual baz to be used might be specified in another @Configuration.

因为我正在创建对象,所以我不需要自动连接它的所有依赖项吗?如果 Baz 有 100 个属性,而我只能明确指定 1 个属性并自动连接其余属性怎么办?

because I'm creating the object, don't I need to auto-wiring all of its dependencies? What if Baz has 100 properties and I only way to specify 1 explicitly and have the rest auto-wired?

AFAIK,基于 xml 的配置没有任何这些问题 - 但我不知所措,因为 spring 手册说你可以通过注释做所有相同的事情.

AFAIK, the xml based configuration doesn't have any of these problems - but I'm at a loss because the spring manual says you can do all the same things via annotations.

注意.我也看到:

@Bean( autowire=Array( classOf[Autowire.BY_TYPE ]) )

也许是可能的.我在网上找不到示例,scala 抱怨(注释参数不是常量).

might be possible. I can't find example online, and scala complains (annotation parameter is not a constant).

[已编辑]

class ApplicationController @Inject() (messagesApi: MessagesApi){
  ... code here ...
}

messagesApi 是一个注入成员

messagesApi is an injected member

https://github 中查看更多信息.com/mohiva/play-silhouette-seed/blob/master/app/controllers/ApplicationController.scala

我发现这很有用

由 Joshua.Suereth 回答.这是简短版本(丑陋但有效"):

Answered by Joshua.Suereth. This is the short version ("ugly but works"):

var service: Service = _; 
@Autowired def setService(service: Service) = this.service = service