@Autowired 在 SimpleJpaRepository 扩展中不起作用 [英] @Autowired does not work in SimpleJpaRepository extension

查看:36
本文介绍了@Autowired 在 SimpleJpaRepository 扩展中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当尝试覆盖 SimpleJpaRepository 时,通过 @Autowired 添加其他 bean 不起作用.这种情况下怎么注入bean呢?这是一个实现:

public class BaseDAOextends SimpleJpaRepository实现 IDAO<T, ID>{@自动连线私人 SomeBean someBean;//空!}

解决方案

BaseDAO 的实例本身不是 Spring 管理的 bean,因此通过 @Autowired 自动装配不会开箱即用.因此需要将依赖项注入到 BaseDAO 实例中.

<小时><块引用>

步骤 1:在某处使用 Spring ApplicationContext

@Component类 SpringContext 实现 ApplicationContextAware {私有静态 ApplicationContext 上下文;public void setApplicationContext(final ApplicationContext context) 抛出 BeansException {上下文 = 上下文;}public static ApplicationContext getContext() { return CONTEXT;}}

这将需要在创建存储库时自动装配自定义存储库实现的依赖项.

<块引用>

第 2 步:扩展 SimpleJpaRepository

class BaseDAOextends SimpleJpaRepository{@自动连线私有依赖依赖;}

<块引用>

第 3 步:通过 JpaRepositoryFactoryBean

自动装配依赖项

class ExtendedJPARepositoryFactoryBean, T, ID extends Serializable>extends JpaRepositoryFactoryBean<R, T, ID>{私有静态类 ExtendedJPARepositoryFactory扩展 JpaRepositoryFactory {公共扩展JPARepositoryFactory(最终EntityManager entityManager){超级(实体管理器);}受保护的类getRepositoryBaseClass(最终 RepositoryMetadata 元数据){返回 isQueryDslExecutor(metadata.getRepositoryInterface())?QueryDSLJPARRepository.class//让您的实现代替 SimpleJpaRepository.:BaseDAO.class;}protected <T, ID extends Serializable>SimpleJpaRepository获取目标存储库(RepositoryInformation 信息,EntityManager entityManager) {//让基类创建存储库.最终 SimpleJpaRepository存储库 = super.getTargetRepository(information, entityManager);//根据需要自动装配依赖项.SpringContext.getContext().getAutowireCapableBeanFactory().autowireBean(存储库);//返回完全设置的存储库.返回存储库;}}protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {返回新的 ExtendedJPARepositoryFactory(entityManager);}}

<块引用>

步骤 4a:配置 Spring Data JPA 以使用您的工厂 bean(XML 配置)

<jpa:repositories base-package="org.example.jpa"factory-class="org.example.jpa.ExtendedJPARepositoryFactoryBean"/>

<块引用>

步骤 4b:配置 Spring Data JPA 以使用您的工厂 bean(Java 配置)

@EnableJpaRepositories(repositoryFactoryBeanClass = ExtendedJPARepositoryFactoryBean.class)

When trying to override SimpleJpaRepository, adding other beans via @Autowired does not work. How can beans be injected in this case? Here is an implementation:

public class BaseDAO<T, ID extends Serializable>
             extends SimpleJpaRepository<T, ID>
             implements IDAO<T, ID> {
  @Autowired
  private SomeBean someBean; // NULL!
}

解决方案

Instances of BaseDAO are not Spring-managed beans in themselves and therefore autowiring through @Autowired will not work out-of-the-box. Dependencies therefore need to be injected into BaseDAO instances.


Step 1: Have a Spring ApplicationContext available somewhere

@Component
class SpringContext implements ApplicationContextAware {
  private static ApplicationContext CONTEXT;

  public void setApplicationContext(final ApplicationContext context) throws BeansException {
    CONTEXT = context;
  }

  public static ApplicationContext getContext() { return CONTEXT; }
}

This will be required to autowire the dependencies for the custom repository implementation at the time of repository creation.

Step 2: Extend SimpleJpaRepository

class BaseDAO<T, ID extends Serializable>
      extends SimpleJpaRepository<T, ID> {
  @Autowired
  private Dependency dependency;
}

Step 3: Autowire dependencies through a JpaRepositoryFactoryBean

class ExtendedJPARepositoryFactoryBean<R extends JpaRepository<T, ID>, T, ID extends Serializable>
      extends JpaRepositoryFactoryBean<R, T, ID> {
  private static class ExtendedJPARepositoryFactory<T, ID extends Serializable> extends JpaRepositoryFactory {
    public ExtendedJPARepositoryFactory(final EntityManager entityManager) {
      super(entityManager);
    }

    protected Class<?> getRepositoryBaseClass(final RepositoryMetadata metadata) {
      return isQueryDslExecutor(metadata.getRepositoryInterface())
             ? QueryDSLJPARepository.class
             // Let your implementation be used instead of SimpleJpaRepository.
             : BaseDAO.class;
    }

    protected <T, ID extends Serializable> SimpleJpaRepository<?, ?> getTargetRepository(
        RepositoryInformation information, EntityManager entityManager) {
      // Let the base class create the repository.
      final SimpleJpaRepository<?, ?> repository = super.getTargetRepository(information, entityManager);

      // Autowire dependencies, as needed.
      SpringContext.getContext()
                   .getAutowireCapableBeanFactory()
                   .autowireBean(repository);

      // Return the fully set up repository.
      return repository;
    }
  }

  protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
    return new ExtendedJPARepositoryFactory(entityManager);
  }
}

Step 4a: Configure Spring Data JPA to use your factory bean (XML configuration)

<jpa:repositories base-package="org.example.jpa"
                  factory-class="org.example.jpa.ExtendedJPARepositoryFactoryBean"/>

Step 4b: Configure Spring Data JPA to use your factory bean (Java configuration)

@EnableJpaRepositories(repositoryFactoryBeanClass = ExtendedJPARepositoryFactoryBean.class)

这篇关于@Autowired 在 SimpleJpaRepository 扩展中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆