spring / scala:可以自动连接bean依赖吗?

时间:2014-08-16 02:18:48

标签: spring scala annotations autowired

我尝试在春天(在scala中)没有xml配置时执行以下操作

<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)
  }
}

我理解几个简单的选择:

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

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

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

  • 将@Bean声明实现为方法:

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

然而:

  • 这种方法规避了自动布线的重点。如果我明确选择了一个参数,baz来设置,那么我需要实际得到它的引用才能做到这一点。通常这可能很困难,特别是如果要使用的实际baz可能在另一个@Configuration中指定。

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

AFAIK,基于xml的配置没有任何这些问题 - 但我感到茫然,因为春季手册说你可以通过注释做同样的事情。

NB。我也看到了:

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

可能是可能的。我无法在线查找示例,并且scala抱怨(注释参数不是常量)。

2 个答案:

答案 0 :(得分:2)

[编辑]

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

messagesApi是注入成员

https://github.com/mohiva/play-silhouette-seed/blob/master/app/controllers/ApplicationController.scala

中查看更多内容

[编辑前]

I'v found this to be usefull

Joshua.Suereth回答。 这是短版本(“丑陋但有效”):

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

答案 1 :(得分:0)

对于自动bean创建,除了在配置级别启用ComponentScan之外,还需要将类注释为Component,Service或Persistence。

所以你可以尝试:

@Component
class Baz {}

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

对于实现相同接口的多个类,您可以为组件和依赖项引用指定名称,即

@Component("baz1")
class Baz {}

@Component("foo1")
class Foo {
   @Resource("baz1")   //?
   @BeanProperty
   val baz:Baz = null
 }

请注意@Autowire已被@Resource取代。