提问者:小点点

如何在@Configuration类中自动连接带有 Spring 注释的服务类?


我试图将一个带服务注释的类注入到一个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;
    }
}


共3个答案

匿名用户

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

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

解决方案

>

  • 由于您的SessionServiceImpl是用@Service注释的,所以您只需删除@Bean方法并让spring创建它。spring已经为您提供了它。

    或者,如果您的SessionServiceImpl没有用@Service注释,则需要以下内容:

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

    如果这不起作用,可能只是因为您的SessionServiceImpl在一个未被spring扫描的包中(正如@MilošMilivojević所建议的)

    您可以将@ComponentScan添加到Configuration类

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

  • 匿名用户

    扩展@Alex的答案,当你用@Bean注释一个方法时,它告诉Spring这个方法将产生那个类型。因此,您本质上告诉Spring为您提供已经对SessionService类型的所有Beans的空引用。

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

    匿名用户

    我在为 Spring 启动应用程序编写集成测试类时遇到了类似的问题。指标 API 的 RestTemplate 类和计数器服务在我的服务类中自动连接。我可以使用@ContextConfiguration(Classes={RestTemplate.class})将RestTemplate注入我的服务,但是将CounterService.class添加到上面的注释中没有帮助,也许是因为CounterService是一个接口而不是一个具体的类,因此我遇到了“找不到计数器服务类型的bean”问题。

    感谢Milos的回答,我在集成测试类中加入了@EnableAutoConfiguration,问题解决了!