如何在@Configuration类中自动装配Spring注释的服务类?

时间:2016-07-12 19:05:28

标签: java spring-boot

我正在尝试将一个带有服务注释的类注入到Spring Boot应用程序的配置类中,但它没有被注入(设置为null),我认为这是由于Spring生命周期。

此外,这个服务有一个使用构造函数注入的重载构造函数,我想这也是一个问题,因为自动装配作用于默认构造函数。但是,该服务需要进行Spring配置,因此我不认为可以在Bean注释方法中创建新实例。

如何解决这个问题?

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private SessionService sessionService;

    @Bean
    public SessionService sessionService() {
        return sessionService;
    }
}

public interface SessionService extends BaseCacheService<Session> {
    void extendExpiration(String key);

    String getSessionId(String key);
}

@Service
public class SessionServiceImpl implements SessionService {

    private Environment environment;
    private UserService userService;

    @Autowired
    public SessionServiceImpl(Environment environment, UserService userService) {
      this.environment = environment;
      this.userService = userService;
    }
}

如果我排除了@Bean方法,那么我得到一个编译错误: Autowire compilation error if no bean found

4 个答案:

答案 0 :(得分:9)

您的错误如下(您将返回空值):

@Bean
public SessionService sessionService() {
    return sessionService;
}

<强>解决方案

  1. 由于您的SessionServiceImpl注释了@Service,因此您可以删除@Bean方法,然后让Spring创建它。 Spring已经为你提供了它。

  2. 或者,如果您的SessionServiceImpl未使用@Service进行注释,则需要以下内容:

  3. @Bean
    public SessionService sessionService() {
       return new SessionService();
    }
    

    如果这不起作用,可能只是你的SessionServiceImpl在一个包裹中没有被春天扫描(正如@MilošMilivojević所建议的那样)

    您可以将@ComponentScan添加到配置类

    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    @ComponentScan("com.package.to.sessionServiceImpl-or-higher")
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    

答案 1 :(得分:1)

扩展@Alex的回答,当你用@Bean注释一个方法时,它会告诉Spring这个方法会生成那个类型。所以,你基本上告诉Spring为你提供了你已经为SessionService类型的所有Beans提供的空引用。

如果您正在使用基于注释的上下文配置,则Autowire任何@Component Bean(不仅仅是@Service)都可以在没有运行时参数的情况下构建(例如,具有默认构造函数或自动构造函数)。如果您需要执行某些操作来创建bean(例如,需要运行时配置),您可以创建@Alex建议的方法,也可以使用getBean并传入Type和Constructor参数。前者通常是优选的。

答案 2 :(得分:1)

在为spring启动应用程序编写集成测试类时,我遇到了类似的问题。 RestTemplate类和CounterService of metrics API在我的服务类中自动装配。我可以使用@ContextConfiguration(Classes = {RestTemplate.class})将RestTemplate注入我的服务,但是将CounterService.class添加到上面的注释没有帮助,可能因为CounterService是一个接口而不是具体的类,因此我得到了&# 34;没有找到CounterService类型的bean&#34;问题。

感谢Milos的回答,我将@EnableAutoConfiguration包含在我的集成测试类中,问题已经解决了!

答案 3 :(得分:0)

如果Alex的答案不起作用(删除@Bean方法),您可能没有使用@EnableAutoConfiguration,或者您的Application不在根层次结构包中,因此它不会扫描整个类路径。尝试将@ComponentScan("service.class.package")添加到您的配置中(除了删除sessionService方法),看看它是否有帮助。