복붙노트

[SPRING] JPA 엔티티 리스너에 대한 스프링 종속성 주입

SPRING

JPA 엔티티 리스너에 대한 스프링 종속성 주입

JPA 엔티티 리스너에 Spring 종속성을 주입해야합니다. 나는 @Configurable과 Spring의 AspectJ weaver를 javaagent로 사용하여 이것을 해결할 수 있다는 것을 알고있다. 그러나 이것은 해킹 된 솔루션처럼 보인다. 내가하려는 일을 성취 할 다른 방법이 있습니까?

해결법

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

    1.또 다른 트릭은 관리 클래스뿐만 아니라 모든 곳에서 Spring 빈을 사용할 수 있도록 도와주는 정적 메소드로 유틸리티 클래스를 구현하는 것이다.

    또 다른 트릭은 관리 클래스뿐만 아니라 모든 곳에서 Spring 빈을 사용할 수 있도록 도와주는 정적 메소드로 유틸리티 클래스를 구현하는 것이다.

    @Component
    public final class BeanUtil {
    
        private static ApplicationContext context;
    
        private BeanUtil(ApplicationContext context) {
            BeanUtil.context = context;
        }
    
        public static <T> T getBean(Class<T> clazz) throws BeansException {
    
            Assert.state(context != null, "Spring context in the BeanUtil is not been initialized yet!");
            return context.getBean(clazz);
        }
    }
    
  2. ==============================

    2.이 솔루션을 사용해 볼 수 있습니다.

    이 솔루션을 사용해 볼 수 있습니다.

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    
    public final class AutowireHelper implements ApplicationContextAware {
    
    private static final AutowireHelper INSTANCE = new AutowireHelper();
    private static ApplicationContext applicationContext;
    
    private AutowireHelper() {
    }
    
    /**
     * Tries to autowire the specified instance of the class if one of the specified beans which need to be autowired
     * are null.
     *
     * @param classToAutowire        the instance of the class which holds @Autowire annotations
     * @param beansToAutowireInClass the beans which have the @Autowire annotation in the specified {#classToAutowire}
     */
    public static void autowire(Object classToAutowire, Object... beansToAutowireInClass) {
        for (Object bean : beansToAutowireInClass) {
            if (bean == null) {
                applicationContext.getAutowireCapableBeanFactory().autowireBean(classToAutowire);
                return;
            }
        }
    }
    
    /**
     * @return the singleton instance.
     */
    public static AutowireHelper getInstance() {
        return INSTANCE;
    }
    
    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) {
        AutowireHelper.applicationContext = applicationContext;
    }
    

    }

    그리고

     @Autowired
    SomeService thatToAutowire;
    
      AutowireHelper.autowire(this, this.thatToAutowire);//this in the method
    
  3. ==============================

    3.Hibernate 5.3 org.hibernate.resource.beans.container.spi.BeanContainer와 Spring 5.1 org.springframework.orm.hibernate5.SpringBeanContainer 이후로 더 이상 autowiring 노력을 할 필요가 없다. 이 기능에 대한 자세한 내용은 https://github.com/spring-projects/spring-framework/issues/20852를 참조하십시오.

    Hibernate 5.3 org.hibernate.resource.beans.container.spi.BeanContainer와 Spring 5.1 org.springframework.orm.hibernate5.SpringBeanContainer 이후로 더 이상 autowiring 노력을 할 필요가 없다. 이 기능에 대한 자세한 내용은 https://github.com/spring-projects/spring-framework/issues/20852를 참조하십시오.

    EntityListener 클래스에 @Component 주석을 달기 만하면 다음과 같이 autowiring을 수행하면됩니다.

    @Component
    public class MyEntityListener{
    
      private MySpringBean bean;
    
      @Autowired
      public MyEntityListener(MySpringBean bean){
        this.bean = bean;
      }
    
      @PrePersist
      public void prePersist(final Object entity) {
        ...
      }
    
    }
    

    Spring Boot에서는 LocalContainerEntityManagerFactoryBean의 설정이 org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration에서 자동으로 수행됩니다.

    Spring Boot 외부에서는 SpringBeanContainer를 Hibernate에 등록해야한다.

    LocalContainerEntityManagerFactoryBean emfb = ...
     emfb.getJpaPropertyMap().put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(beanFactory));
    
  4. from https://stackoverflow.com/questions/47941717/spring-dependency-injection-into-jpa-entity-listener by cc-by-sa and MIT license