2011-02-15 160 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级别的单例,即编译器强制的单例,以及容器单例。