복붙노트

[SPRING] NULL을 반환하는 싱글 톤과 @Autowired

SPRING

NULL을 반환하는 싱글 톤과 @Autowired

내 리포지토리를 관리하는 리포지토리 관리자가 있습니다. @Autowired를 사용하여 내 속성을 인스턴스화하지만 항상 null입니다. 콩은 내 XML에 올바르게 구성되어 있습니다. 이유가 뭐야?

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;
        }
    }

.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);
    }

해결법

  1. ==============================

    1.방금 나 자신을 만났어. 문제는 당신이 그렇게 할 때입니다.

    방금 나 자신을 만났어. 문제는 당신이 그렇게 할 때입니다.

    new RepositoryManager();
    

    Instance ()에서 Spring을 사용하여 RepositoryManager를 작성하지 않으므로 종속성 삽입이 인스턴스에 발생하지 않습니다 (자동 연결 없음).

    해결 방법은 Instance () 싱글 톤 패턴을 없애는 것입니다. Singleton을 고집하고 싶다면 다음을 수행하십시오.

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

    그런 다음 저장소 관리자가 필요한 곳이면 어디서나 저장소에 대한 참조가 자동으로 작성됩니다 (호출하는 bean도 Spring에서 관리한다고 가정).

    @Autowired
    private RepositoryManager repositoryManager = null;
    
  2. ==============================

    2.설정에 다음 항목이 있는지 확인하십시오.

    설정에 다음 항목이 있는지 확인하십시오.

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

    그런 다음 구성 XML을 게시 할 경우

  3. ==============================

    3.실제로 케이크를 먹고 먹는, 즉 봄에 관리되는 JVM 싱글 톤을 갖는 매우 우아한 방법이 있습니다. 다음과 같이 autowired 빈을 가진 순수한 자바 싱글 톤이 있다고 가정 해보십시오.

    실제로 케이크를 먹고 먹는, 즉 봄에 관리되는 JVM 싱글 톤을 갖는 매우 우아한 방법이 있습니다. 다음과 같이 autowired 빈을 가진 순수한 자바 싱글 톤이 있다고 가정 해보십시오.

    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"/>
    

    이제 당신의 싱글 톤은 Autowired SomeSpringBean의 인스턴스를 가질 것입니다 (컨텍스트에서 사용 가능한 경우).

    더욱이 이것은 스프링에 의해 인스턴스화되기 때문에 진정한 JVM 싱글 톤이 아닌 Spring 싱글 톤 빈의 전형적인 문제에 대한 '수정'입니다. 위 패턴을 사용하면 컨테이너 싱글 톤과 함께 JVM 레벨 싱글 톤, 즉 컴파일러 적용 싱글 톤이 적용됩니다.

  4. ==============================

    4.이 문제가 발생하는 이유는 정적 메서드 Instance ()

    이 문제가 발생하는 이유는 정적 메서드 Instance ()

    당신은 스프링 컨텍스트 외부에서 POJO를 생성하고있다.

    를 컨피규레이션에 추가 한 다음 RepositoryManager에 @Configurable으로 주석을 달아 이것을 수정할 수있다.

  5. from https://stackoverflow.com/questions/5010219/singleton-and-autowired-returning-null by cc-by-sa and MIT license