2011-02-15 161 views
9

我有一個存儲庫管理器來管理我的存儲庫。我有@Autowired來實例化我的屬性,但它們始終爲空。這些bean在我的xml中正確配置。任何理由?Singleton和@Autowired返回NULL

public class RepositoryManager { 

     private static RepositoryManager instance; 

     private RepositoryManager() 
     { 
     } 

     public static RepositoryManager Instance() 
     { 
      if(instance == null) 
       instance = new RepositoryManager(); 

      return instance; 
     } 

     @Autowired 
     private IUserRepository userRepository; 

     @Autowired 
     private IRoleRepository roleRepository; 

     @Autowired 
     private IAssetRepository assetRepository; 

     public IUserRepository getUserRepository() { 
      return userRepository; 
     } 

     public void setUserRepository(IUserRepository userRepository) { 
      this.userRepository = userRepository; 
     } 

     public IRoleRepository getRoleReposttory() { 
      return roleRepository; 
     } 

     public void setRoleReposttory(IRoleRepository roleRepository) { 
      this.roleRepository = roleRepository; 
     } 

     public IAssetRepository getAssetRepository() { 
      return assetRepository; 
     } 

     public void setAssetRepository(IAssetRepository assetRepository) { 
      this.assetRepository = assetRepository; 
     } 
    } 

dao.xml

<!-- Scans within the base package of the application for @Components to configure as beans --> 
    <context:component-scan base-package="com.cisco.badges.data.*" /> 

    <context:property-placeholder location="classpath:jdbc.properties"/> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <property name="driverClassName" value="${jdbc.driverClassName}"/> 
     <property name="url" value="${jdbc.url}"/> 
     <property name="username" value="${jdbc.username}"/> 
     <property name="password" value="${jdbc.password}"/> 
     </bean> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/> 
     <property name="annotatedClasses"> 
      <list> 
       <value>com.cisco.badges.data.domain.User</value> 
       <value>com.cisco.badges.data.domain.Role</value> 
       <value>com.cisco.badges.data.domain.Asset</value> 
       <value>com.cisco.badges.data.domain.UserRole</value> 
       <value>com.cisco.badges.data.domain.UserRole$UserRolePK</value> 
       <value>com.cisco.badges.data.domain.UserAsset</value> 
       <value>com.cisco.badges.data.domain.UserAsset$UserAssetPK</value> 
      </list> 
     </property> 
     <property name="configLocation"> 
      <value>classpath:hibernate.cfg.xml</value> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="hibernate.format_sql">true</prop> 
      </props> 
     </property> 
    </bean> 

    <tx:annotation-driven/> 

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

</beans> 

userrepository.java

@Repository("userRepository") 
public class UserRepository extends 
     BaseRepository<User, Long> implements 
     IUserRepository { 

    @Autowired 
    public UserRepository(SessionFactory sessionFactory) { 
     super(sessionFactory); 
    } 
+0

如果beans *被正確配置,那麼您的字段不會爲空。向我們展示配置。 – skaffman 2011-02-15 22:25:22

+0

我添加了xml和示例存儲庫。同一個存儲庫可以手動注入,它是控制器中的一個屬性,但是在這個靜態方法中,它沒有被填充。 – 2011-02-15 22:30:56

+0

(a)爲什麼`RepositoryManager`管理自己的單身人士? (b)Spring中定義了RepositoryManager?它是什麼包? (c)當你已經聲明組件掃描時,爲什麼要聲明顯式的存儲庫bean? – skaffman 2011-02-15 22:47:55

回答

5

請確保你在你的配置如下:

<context:annotation-config /> 

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

如果你擁有了它然後發佈您的配置xml

21

我剛碰到這個。問題是,當你在實例()做

new RepositoryManager(); 

,你是不是使用Spring構建RepositoryManager,因此,依賴注入是不會發生的您的實例(無自動裝配)。

解決方案是取消Instance()單例模式。如果你想堅持一個Singleton,然後做這個

@Component 
@Scope(value = "singleton") 
public class RepositoryManager { 
    ... 
} 

那麼無論你需要的資源庫管理,只是它的一個引用自動裝配(假設主叫豆也由Spring管理!)

@Autowired 
private RepositoryManager repositoryManager = null; 
0

出現這種情況的原因是因爲靜態方法Instance()

要創建Spring上下文之外的POJO的。

您可以通過添加<context:spring-configured />到您的配置,然後用@Configurable

3

其實是有註釋RepositoryManager一個非常優雅的方式有你魚與熊掌兼得,即解決這個問題,有一個JVM單這也是春天-管理。假設你有一個自動裝配Autowired豆像這樣的純java單:

public final class MySingletonClass{ 
    private static MySingletonClass instance; 

    public static MySingletonClass getInstance(){ 
    if(instance==null){ 
     synchronized{ 
     if(instance==null){ 
      instance = new MySingletonClass(); 
     } 
     } 
    } 
    return instance; 
    } 

    @Autowired 
    private SomeSpringBean bean; 

    // other singleton methods omitted 
} 

您可以強制Spring來管理這個單隻需在您的應用程序上下文中加入如下一行:

<bean class="com.mypackage.MySingletonClass" factory-method="getInstance"/> 

現在你的單身將具有自動裝配的SomeSpringBean實例(如果在上下文中可用)。另外,這是對於Spring單例bean的典型問題的「修復」,它不是真正的JVM單例,因爲它們被Spring實例化。使用上面的模式強制JVM級別的單例,即編譯器強制的單例,以及容器單例。