依赖注入是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方法即可实现按需注入所需的属性。

 

 
  
  1. package org.jsi.di.spring; 
  2.  
  3. import org.apache.commons.logging.Log; 
  4. import org.apache.commons.logging.LogFactory; 
  5. import org.springframework.beans.BeansException; 
  6. import org.springframework.beans.factory.BeanFactory; 
  7. import org.springframework.beans.factory.BeanFactoryAware; 
  8. import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 
  9.  
  10.  
  11. public class RichDomainObjectFactory implements BeanFactoryAware { 
  12.  
  13.     private static final Log LOG = LogFactory.getLog(RichDomainObjectFactory.class); 
  14.  
  15.     private AutowireCapableBeanFactory factory = null
  16.  
  17.     public <T> T createAndAutowire(Class<T> clazz) { 
  18.         T instance = null
  19.         try { 
  20.             instance = clazz.newInstance(); 
  21.             autowire(instance); 
  22.         } catch (InstantiationException e) { 
  23.             throw new RuntimeException(e); 
  24.         } catch (IllegalAccessException e) { 
  25.             throw new RuntimeException(e); 
  26.         } 
  27.         return instance; 
  28.     } 
  29.  
  30.     public void autowire(Object instance) { 
  31.         if (factory != null) { 
  32.             factory.autowireBeanProperties(instance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false); 
  33.         } else { 
  34.             LOG.warn("No " + AutowireCapableBeanFactory.class.getName() + " has been defined. Autoworing will not work."); 
  35.         } 
  36.     } 
  37.  
  38.     public void setBeanFactory(BeanFactory factory) throws BeansException { 
  39.         this.factory = (AutowireCapableBeanFactory) factory; 
  40.     } 
  41.  
  42.     private static RichDomainObjectFactory singleton = new RichDomainObjectFactory(); 
  43.  
  44.     public static RichDomainObjectFactory autoWireFactory() { 
  45.         return singleton; 
  46.     } 
  47.  
  48.     public static void setInstance(RichDomainObjectFactory richDomainObjectFactory) { 
  49.         singleton = richDomainObjectFactory; 
  50.     } 
  51.  

如上,在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等注入了