Reputation: 15800
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>
where we have:
class Baz {}
class Foo {
@Autowired //?
@BeanProperty
val baz:Baz = null
}
I have the following test setup:
@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 -- this approach has several issues:
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
}
However:
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.
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, 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.
NB. I also see:
@Bean( autowire=Array( classOf[Autowire.BY_TYPE ]) )
might be possible. I can't find example online, and scala complains (annotation parameter is not a constant).
Upvotes: 0
Views: 2085
Reputation: 1803
[edited]
class ApplicationController @Inject() (messagesApi: MessagesApi){
... code here ...
}
messagesApi is an injected member
see more in https://github.com/mohiva/play-silhouette-seed/blob/master/app/controllers/ApplicationController.scala
[before edit]
Answered by Joshua.Suereth. This is the short version ("ugly but works"):
var service: Service = _;
@Autowired def setService(service: Service) = this.service = service
Upvotes: 2
Reputation: 718
For automatic bean creation you need to annotate the classes as Component, Service or Persistence, in addition to enabling the ComponentScan at config level.
So you can try:
@Component
class Baz {}
@Component
class Foo {
@Autowired //?
@BeanProperty
val baz:Baz = null
}
For multiple classes implementing the same interface, you can specify names to both the component and the dependency references, i.e.
@Component("baz1")
class Baz {}
@Component("foo1")
class Foo {
@Resource("baz1") //?
@BeanProperty
val baz:Baz = null
}
Notice the @Autowire has been replaced by @Resource.
Upvotes: 0