依赖注入是Spring的一大特色,日常使用中,我们通常直接在配置文件或者使用注解,或者单例,或者工厂模式,在spring容器初始化时就将所有要用到的对象初始化好,然而有时我们想要只在自己new一个类时,用spring注入某个属性,如下:
class PersonDao{
@Value("${insertSql}")
val insertSql:String = _
def save(){..}
....
}
class Person extends PersonDao{
...
}
目标是new Person时类似@Value这些自动注入的属性可以加载,实现策略如下,设计一个单例类使其实现BeanAwareFactory,来只想Spring的工厂类,并将其作为一个bean有spring加载,由于是单例模式,那其他类也可以获取这个工厂对象,之后调用该对象的autoWire方法即可实现按需注入所需的属性。
- package org.jsi.di.spring;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- 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 RichDomainObjectFactory implements BeanFactoryAware {
- private static final Log LOG = LogFactory.getLog(RichDomainObjectFactory.class);
- private AutowireCapableBeanFactory factory = null;
- public <T> T createAndAutowire(Class<T> clazz) {
- T instance = null;
- try {
- instance = clazz.newInstance();
- autowire(instance);
- } catch (InstantiationException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- return instance;
- }
- public void autowire(Object instance) {
- if (factory != null) {
- factory.autowireBeanProperties(instance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
- } else {
- LOG.warn("No " + AutowireCapableBeanFactory.class.getName() + " has been defined. Autoworing will not work.");
- }
- }
- public void setBeanFactory(BeanFactory factory) throws BeansException {
- this.factory = (AutowireCapableBeanFactory) factory;
- }
- private static RichDomainObjectFactory singleton = new RichDomainObjectFactory();
- public static RichDomainObjectFactory autoWireFactory() {
- return singleton;
- }
- public static void setInstance(RichDomainObjectFactory richDomainObjectFactory) {
- singleton = richDomainObjectFactory;
- }
- }
如上,在spring的配置文件中,写入:
<bean class="org.jsi.di.spring.RichDomainObjectFactory " factory-method="autoWireFactory"/>
这样,我们再实现Person的Object
Object Person{
def apply(name:String) = RichDomainObjectFactory.autoWireFactory().autowire(new Person(name))
}
后面new一个Person类时,直接调用Person(“alfred")就可以了,这样生成的Person类已经将insertSql等注入了