2011-02-15 7 views
9

내 리포지토리를 관리하는 리포지토리 관리자가 있습니다. @Autowired는 내 속성을 인스턴스화하지만 항상 null입니다. 콩은 내 XML에 올바르게 구성되어 있습니다. 이유가 뭐야?싱글 톤과 @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

빈 *을 올바르게 구성한 경우 필드가 null이되지 않습니다. 설정을 보여주십시오. – skaffman

+0

xml 및 샘플 리포지토리를 추가했습니다. 같은 저장소를 수동으로 컨트롤러에있는 속성으로 주입 할 수 있지만이 정적 메서드에서는 채워지지 않습니다. –

+0

(a) 왜'RepositoryManager'는 자신의 싱글 톤을 관리합니까? (b) Spring에 'RepositoryManager'가 정의 된 곳은 어디입니까? 어떤 패키지입니까? (c) 당신이 이미 컴포넌트 스캔을 선언했을 때 명시 적 저장소 빈을 선언하는 이유는 무엇입니까? – skaffman

답변

5

당신이 가지고 있는지 확인하십시오 당신의 설정에 다음

<context:annotation-config /> 

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

당신이있는 경우 그런 다음 구성 XML을 게시하십시오

+0

주석 구동 및 구성 요소 스캔 –

+0

이 예제를 보려면 가 필요하다고 생각합니다. http://www.mkyong.com/spring/spring-auto-wiring- beans-with-autowired-annotation/그리고 나는 또한 나의 코드를보고 거기에 그것을 본다. –

+0

같은 것. 나는 그것의 싱글 톤 부분과 관련이 있다고 생각 하는가? –

21

나는 이걸 직접 만났어. 문제는 당신이 인스턴스()에

new RepositoryManager(); 

을 수행 할 때, 당신은 RepositoryManager를 만드는 스프링을 사용하지 않는, 따라서 의존성 주입이 인스턴스 (NO를 autowiring)에 대한 발생되지 않는 것입니다.

해결책은 Instance() 단독 패턴을 제거하는 것입니다. 당신이 싱글을 주장하려면, 다음 저장소 관리자를 필요로 어디든지, 그냥에 대한 참조를 autowire하기 그런 다음이

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

을 (호출 콩도 스프링에 의해 관리되는 가정!)

@Autowired 
private RepositoryManager repositoryManager = null; 
이런 일이
+0

+1 좋은 샷. 감사. –

0

이유 때문에 당신이 스프링 컨텍스트 외부에서 POJO를 작성하는 정적 메소드 Instance()

이다.

당신이, 즉, 당신의 케이크가 있고 그것을 먹고 매우 우아한 방법을 구성에 <context:spring-configured />를 추가하고 거기에 실제로 @Configurable

3

RepositoryManager을 주석하여이를 해결 또한 봄의 JVM이 싱글을 가질 수 있습니다 관리. 당신의 싱글 이제

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

: 단순히 응용 프로그램 컨텍스트에서 다음 줄을 추가하여

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 
} 

당신이 싱글을 관리하는 봄 강제 할 수 있습니다 :이 같은 autowire가 콩 순수 자바 싱글을 말해봐 autowired SomeSpringBean의 인스턴스를 갖습니다 (컨텍스트에서 사용 가능한 경우).

또한 스프링으로 인스턴스화되기 때문에 진정한 JVM 싱글 톤이 아닌 스프링 싱글 톤 빈의 일반적인 문제에 대한 '수정'입니다. 위 패턴을 사용하면 컨테이너 싱글 톤과 함께 JVM 수준의 싱글 톤 (즉, 컴파일러 적용 싱글 톤)이 적용됩니다.

관련 문제