CustomInterceptor中自动装配获取null(Spring Boot)

Raj*_*ami 7 java java-8 spring-boot

我想在收到请求时在数据库中进行检查.所以我做了如下的拦截器,

CustomInterceptor.java

@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {

@Autowired
private DatabaseService databaseService;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //Set Request Attribute(TODO)
    LogService.info(this.getClass().getName(), "New Request URI is:" + request.getRequestURI());
    return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    String authToken = request.getHeader("AuthToken");
        boolean isValidRequest = databaseService.checkIfTokenIsValid(authToken);
    }
}
Run Code Online (Sandbox Code Playgroud)

Application.class:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

//    protected Properties props = new Properties();
//
//    public Application() {
//        props.setProperty("error.path", "/error");
////        props.setProperty("error.whitelabel.enabled", "false");
////        props.setProperty("org.springframework.web", "DEBUG");
//    }
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
//        application.properties(props);
    return application.sources(Application.class);
}

@Override
public void onStartup(final ServletContext servletContext) throws ServletException {
    LogService.info(Application.class.getName(), "Loading Service...");
    super.onStartup(servletContext);
    LogService.info(Application.class.getName(), "Service Started");
}

public static void main(String[] args) {
    ApplicationContext context = SpringApplication.run(Application.class, args);
}
Run Code Online (Sandbox Code Playgroud)

DatabasService.java

@Service
public class DatabaseService {


@Autowired
private ApplicationProperties properties;

private final JdbcTemplate defaultJdbcTemplate;

@Autowired
public DatabaseService(
        @Qualifier("dataSource") DataSource dataSource) {
    defaultJdbcTemplate = new JdbcTemplate(dataSource);
}

public boolean checkIfTokenIsValid() {
    //Perform Check
 }
}
Run Code Online (Sandbox Code Playgroud)

CustomWebConfiguration.java

@Configuration
@EnableWebMvc
public class CustomWebConfiguration extends WebMvcConfigurerAdapter {

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
    "classpath:/META-INF/resources/", "classpath:/resources/",
    "classpath:/static/", "classpath:/public/"};

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!registry.hasMappingForPattern("/**")) {
        registry.addResourceHandler("/**").addResourceLocations(
                CLASSPATH_RESOURCE_LOCATIONS);
    }
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new CustomInterceptor())
            .addPathPatterns("/**");
}
Run Code Online (Sandbox Code Playgroud)

}

但是我得到了NullPointer: boolean isValidRequest = databaseService.checkIfTokenIsValid(authToken);

这里有什么问题,为什么Spring不能在Interceptor中自动装配Databaseservice?

注意:Autowire在其他任何地方都可以正常工作,但在拦截器中却不行.

解决方案(感谢M. Deinum) 更改下面的CustomWebConfiguration.java;

@Configuration
@EnableWebMvc
public class CustomWebConfiguration extends WebMvcConfigurerAdapter {

private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
    "classpath:/META-INF/resources/", "classpath:/resources/",
    "classpath:/static/", "classpath:/public/"};

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!registry.hasMappingForPattern("/**")) {
        registry.addResourceHandler("/**").addResourceLocations(
                CLASSPATH_RESOURCE_LOCATIONS);
     }
    }

@Bean
public CustomInterceptor customInterceptor() {
    return new CustomInterceptor();
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(customInterceptor())
            .addPathPatterns("/**");
 }
}
Run Code Online (Sandbox Code Playgroud)

M. *_*num 7

Spring只会自动装配它知道的bean,你自己在Spring的控制之外创建实例.

将a CustomInterceptor注入配置类或添加@Bean方法以使其成为Spring托管实例.然后使用该实例将其添加到拦截器列表中.