2011-12-01 13 views
7

Ben Scala ile Bahar kullanmaya çalışıyorum. Ben Autowired Scala sınıfı ile çalışır biliyorum ama bir nesneyi gerektiren bir web framework kullanıyorum ve bunun içine bir Dao enjekte etmek istiyorum. Bunu nasıl yapacağımı merak ediyorum? Üzgünüm, Scala için oldukça yeni, şimdiden teşekkürler.Scala nesnesinde Bahar Otomatik Kablolu (veya manüel olarak kablolu) nasıl kullanılır?

@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> 
+0

neden burada bir nesne ihtiyacım var? yine '@Service sınıfı Merhaba {@Autowired var Repo: Depo = _}' Eğer bileşen tarama yapılandırılmış ettik varsayarak veya oldukça havalı AnnotationConfigApplicationContext – OlegYch

cevap

12

Temel olarak, iki sorun vardır: Yay örnek yöntemleri beklediğini ise

  • İşletme kesilebilir olması gerekir, yani, var yerine Scala object arasında val

  • Tüm yöntemler, static bulunmaktadır. Aslında Scala sahnenin arkasında UserRest$ adlandırılmış örnek yöntemleriyle bir sınıf oluşturur ve Bahar onun tekil örneği UserRest$.MODULE$ kullanılabilir yapmak gerekir.
    Yay tekil örnekleri, önceden var olan yapılandırmayı uygulayabilir, ancak UserRest$.MODULE$ bir alandır Bu, böyle bir yöntem ile döndürülmelidir. Böylece, onu döndürmek için bir yöntem oluşturmanız gerekir.

Yani, böyle bir şey çalışması gerekir:

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> 

Sen @Autowired ile <property> yerine geçebilir, fakat yukarıda açıklanan tekil örneği sorunlara @Service manuel fasulye beyanı yerini alamaz.

Ayrıca bakınız:

+0

kullanarak, iyi çalışması gerekir. Bahar 3.1 ile xml olmayan bir yolu var mı merak ediyorum. – sourcedelica

+0

@ericacm: Aslında, bir '@ Configuration' nesnesi oluşturabilir ve' Bean’in açıklamalı yönteminden 'UserRest $ .MODULE $ 'döndürebilirsiniz. İlkbahar 3.0'da zaten mevcut. – axtavt

+0

Evet - iyi nokta. – sourcedelica

1

Ne yapmam inşaat anda nesne enjekte AutowiredAnnotationBeanPostProcessor kullanmaktır. Örneğin

:

object UserRest extends RestHelper { 
    @Autowired 
    var userRepository: UserRepository = _ 

    AppConfig.inject(this) 
} 

@Configuration 
class AppConfig extends ApplicationListener[ContextRefreshedEvent] { 

    // Set the autowiredAnnotationBeanPostProcessor when the Spring context is initialized 
    def onApplicationEvent(event: ContextRefreshedEvent) { 
    autowiredAnnotationBeanPostProcessor = 
     event.applicationContext. 
     getBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME). 
      asInstanceOf[AutowiredAnnotationBeanPostProcessor] 
    } 
} 

object AppConfig { 
    var autowiredAnnotationBeanPostProcessor: AutowiredAnnotationBeanPostProcessor = null 

    def inject(obj: AnyRef) { 
    autowiredAnnotationBeanPostProcessor.processInjection(obj); 
    } 
} 

Şimdi olan yaşam döngüsü Spring tarafından kontrol edilmeyen herhangi bir nesne enjekte AppConfig.inject() kullanabilir. vb Örneğin, JPA varlıkları,

4

için tüm aslında gerekli sen bir nesne yerine, bir sınıf olarak nesneyi tanımlamak olmasıdır. Bu şekilde Spring bunu başlatacak. "Değişken" "val" Değiştirme

@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> 

(Yay değişmezlik göz ardı yansıma kullanır) gereksizdir. O @BeanProperty (Bahar Düşünceli, altta yatan alana tahsis edecektir) da gereksiz olduğunu eminim.

3

axtavt çözümü için beni işe yaramadı, ancak diğer cevaplar farklı önerileri birleştirerek bu en zarif çözüm olduğunu düşünüyorum:

object User { 
    @Autowired val repo: UserRepository = null 

    def instance() = this 
} 

@Configuration 
class CompanionsConfig { 
    @Bean def UserCompanion = User.instance 
} 

<context:component-scan base-package="your-package" /> 

birkaç not:

  • @Configuration sağlar kullanma senin arkadaşı nesneler heyecanla @Bean def kullanma
  • autowired olduğunu Scala arkadaşı nesne uygulayan sınıfa verir gürültülü isimlerle uğraşmak zorunda önler
  • Dave Griffith tarafından belirtildiği gibi
  • val, gayet güzel çalışıyor
  • Scala'nın @BeanProperty için gerek yoktur
  • , Bahar ek olarak (I 3.2.2 kullanıyorum)
0

kutunun dışında Scala özelliklerini anlar https://stackoverflow.com/a/8344485/5479289, fabrika yöntemi kullanılarak, içerik, hem de skala nesne Bahar scala paket nesnesi eklemek de mümkündür. Derlenmiş paket nesnesi, paketi isimli normal java sınıfıdır, böylece bunu Bahar içeriğine ekleyebilirsiniz. Bundan sonra, yani bu nesnenin içindeki tüm Spring'in olanağa sahip olacaktır @Autowired, @value, manuel kablolama vb

Testi paketi:

package my.module 

package object A { 
    def getInstance = this 

    @Autowired 
    private val b: B = null 
} 

Ve bahar bağlam xml geçerli:

<beans ...> 
    ... 
    <bean id="a" class="my.module.A.package" factory-method="getInstance"/> 
    ... 
</beans> 
İlgili konular