Spring 依赖注入在单例中不起作用 class

Spring Dependency Injection not working in singleton class

我做了一个名为 AcessoCliente

的单例 class
public class AcessoCliente {

    private HashMap<String, Cliente> clientes;
    private new HashMap<String, Date> clientesNaoEncontrados;

    private static AcessoCliente instance;

    static {
        instance = new AcessoCliente();
    }

    public static AcessoCliente get() {
        return instance;
    }

    private AcessoCliente() {
        clientes = new HashMap<String, Cliente>();
        clientesNaoEncontrados = new HashMap<String, Date>();
    }

    /*business*/
}

但是我需要在我的单例上对名为 ValidadorNivelDeAcessoBusiness 的 class 进行依赖注入 class

@Component
public class ValidadorNivelDeAcessoBusiness {

    @Autowired
    QuerysNiveisDeAcesso querysNiveisDeAcesso;
    /*business*/
}

我正在尝试执行此依赖项注入但没有用,这就是我所做的:

public class AcessoCliente {

    @Autowired
    ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness;

    private HashMap<String, Cliente> clientes;
    private new HashMap<String, Date> clientesNaoEncontrados;

    private static AcessoCliente instance;

    static {
        ApplicationContext context = new AnnotationConfigApplicationContext(AcessoCliente.class);
        instance = context.getBean(AcessoCliente.class);
    }

    public static AcessoCliente get() {
        return instance;
    }

    private AcessoCliente() {
        clientes = new HashMap<String, Cliente>();
        clientesNaoEncontrados = new HashMap<String, Date>();
    }

    /*business*/
}

但是依赖项注入不起作用,我收到此错误:

Error creating bean with name 'acessoCliente': Unsatisfied dependency expressed through field 'validadorNivelDeAcessoBusiness'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'my.project.business.interceptorBusiness.ValidadorNivelDeAcessoBusiness' available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

编辑1。那就是 QuerysNiveisDeAcesso class

@Component
public class QuerysNiveisDeAcesso extends QuerysClientes {

    public QueryIntegratorBuilder queryBuscaNiveisDeAcesso(String[] condicoesQuery) throws Exception {
        return super.executaQuery("BUSCA_NIVEIS_DE_ACESSO", condicoesQuery);
    }

    public QueryIntegratorBuilder queryBuscaNiveisDeAcesso() throws Exception {
        return super.executaQuery("BUSCA_NIVEIS_DE_ACESSO");
    }

    public QueryIntegratorBuilder queryBuscaNiveisDeAcesso(String sqlWhere, String[] condicoesQuery) throws Exception {
        return super.executaQuery("BUSCA_NIVEIS_DE_ACESSO", condicoesQuery, sqlWhere);
    }

}

您完全误用了 spring 的目的。

首先,在 AcessoCliente class.

中创建应用程序上下文没有意义

应用程序上下文是一个“全局”spring 的注册表对象,通常在整个应用程序中只存在一次。

如果您使用的是 Plain Spring - 您可以在 public static void main 方法中创建应用程序上下文。然后从那里得到豆子。

接下来,当您创建应用程序上下文时,您应该将配置对象传递给它,而不是单个 class。您还可以使用组件扫描,有很多技术。但总而言之,它应该接受“规则”来配置 - 阅读查找并加载 beans。

现在让return到AccessClienteclass。您已将其定义为具有静态方法和私有构造函数的单例,没关系。但它不适用于 spring - 事实上,如果你使用 spring,你可以使这个 class 成为单例,从某种意义上说,整个中只有一个 bean应用上下文。 这更易于管理和清晰(+ 没有样板代码)。 事实上,在 spring 宇宙中,默认情况下所有 bean 都是单例。

接下来要提到的是当你创建一个单例bean(一个class,它的实例由spring管理)然后整个自动装配魔法将自动开始工作。

你所做的是一个奇怪的混合体,无论如何都不会工作(如果没有指示,spring 如何创建一个 bean,即使是,构造函数也是私有的) .

所以,回顾一下,您需要这样的东西:

public class Main {
   public static void main(String  [] args) {
     ApplicationContext ctx = ...;
     ctx.getBean(SomeClassThatStartsTheFlow.class).doSomething();
   }    
}

@Service
public class AcessoCliente {

    @Autowired
    ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness;

    private HashMap<String, Cliente> clientes;
    private new HashMap<String, Date> clientesNaoEncontrados;

    public AcessoCliente() {
        clientes = new HashMap<String, Cliente>();
        clientesNaoEncontrados = new HashMap<String, Date>();
    }

    /*business*/
}

我已尝试重现您遇到的相同问题,似乎您在 ValidadorNivelDeAcessoBusiness class 中的依赖项正在尝试加载,但是此 [=23] 中的字段之一=] 可能缺少 @Component 注释,以便加载 Spring 应用程序上下文。

@Component public class AcessoCliente {
    @Autowired
    ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness;
}

@Component
public class ValidadorNivelDeAcessoBusiness {

   @Autowired
   QuerysNiveisDeAcesso querysNiveisDeAcesso;
}

public class QuerysNiveisDeAcesso {
   // some code
}

会产生以上错误:'acessoCliente': Unsatisfied dependency expressed through field 'validadorNivelDeAcessoBusiness'

确保 ValidadorNivelDeAcessoBusiness 中的所有字段都有一个 @Component 让 spring 应用程序上下文工作,即:

@Component 
public class QuerysNiveisDeAcesso {
      // some code
}

您正在尝试混合 Java 单例和 Spring 单例。

为了使其与普通 java 和 spring 兼容,您应该在参数中使用注入的服务创建静态工厂方法,并在 @Configuration 文件中创建单例 bean。

public class AcessoCliente {

  ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness;

  private HashMap<String, Cliente> clients;
  private HashMap<String, Date> clientesNaoEncontrados;

  private static AcessoCliente instance;

  public static AcessoCliente getInstance(ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness) {
    if(instance == null) {
      instance = new AcessoCliente(validadorNivelDeAcessoBusiness);
    }
    return instance;
  }

  private AcessoCliente(ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness) {
    clientes = new HashMap<String, Cliente>();
    clientesNaoEncontrados = new HashMap<String, Date>();
    this.validadorNivelDeAcessoBusiness = validadorNivelDeAcessoBusiness;
  }
}

@Configuration
public class AcessoClienteConfiguration
{    
  @Bean
  @Scope("singleton")
  public AcessoCliente acessoCliente(ValidadorNivelDeAcessoBusiness validadorNivelDeAcessoBusiness)
  {
    return AcessoCliente.getInstance(validadorNivelDeAcessoBusiness);
  }
}