以下のような BeanFactoryAware
を implements したクラスを用意。
ここは java で書いた。
このクラスの autowire(instance)
メソッドで、指定した instance に対して手動で autowire できる。
package foo.bar.example;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
public class AutowiredObjectFactory implements BeanFactoryAware {
private AutowireCapableBeanFactory factory = null;
private static AutowiredObjectFactory singleton = new AutowiredObjectFactory();
public static AutowiredObjectFactory autoWiredObjectFactory() {
return singleton;
}
public <T> T autowire(T instance) {
factory.autowireBeanProperties(
instance,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE,
true);
return instance;
}
public void setBeanFactory(BeanFactory factory) throws BeansException {
this.factory = (AutowireCapableBeanFactory) factory;
}
}
使う側。
package foo.bar.example
import javax.sql.DataSource
import domala.jdbc.Naming
import domala.jdbc.dialect.{Dialect, H2Dialect}
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
object DomalaConfig extends SpringTransactionConfig(
dialect = new H2Dialect(),
naming = Naming.SNAKE_LOWER_CASE
) {
Class.forName("org.h2.Driver")
}
abstract class SpringTransactionConfig(
dialect: Dialect,
naming: Naming = Naming.NONE
) extends domala.jdbc.Config {
@Autowired
val dataSource: DataSource = null
//または var dataSource: DataSource = _
override def getDataSource: DataSource = new TransactionAwareDataSourceProxy(dataSource)
override def getDialect: Dialect = dialect
override def getNaming: Naming = naming
}
object DomalaConfigFactory {
import foo.bar.example.AutowiredObjectFactory._
def apply() = autoWiredObjectFactory().autowire(DomalaConfig)
}
上記の DomalaConfigFactory
内で以下のようにしている。
import foo.bar.example.AutowiredObjectFactory._
def load() = autoWiredObjectFactory().autowire(DomalaConfig)
今回はシングルトンオブジェクトに対して Autowired したオブジェクトを作りたかったので、
autowire メソッドには DomalaConfig
(DomalaConfig.apply)を渡している。
これで、 DomalaConfigFactory#load
を呼び出せば、
Autowired 済みの object が手に入る。
implicit lazy val config: Config = DomalaConfigFactory.load
参考: Scala & Spring: Combine the best of both worlds
別解:
How to use Spring Autowired (or manually wired) in Scala object? - Stack Overflow
object User {
@Autowired val repo: UserRepository = null
def instance() = this
}
@Configuration
class CompanionsConfig {
@Bean def UserCompanion = User.instance
}
@Configuraiton
なクラスに companion のインスタンスを返すメソッドを用意して、それを @Bean
する。
で、上記の例だと UserCompanion
を DI することで Autowired 済み object を DI できる。
なんだけどこれ、DIして使う想定ならそもそも object にしなければいいんじゃ・・・