Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autowired in CustomInterceptor getting null(Spring Boot) [duplicate]

I want to make a check in database when i receive a request. So i did a Interceptor like below,

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);
    }
}

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);
}

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
 }
}

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("/**");
}

}

But i get NullPointer At: boolean isValidRequest = databaseService.checkIfTokenIsValid(authToken);

What is wrong here, why cannot spring Autowire the Databaseservice in Interceptor?

Note: Autowire works fine everywhere else, but not in the interceptor.

Solution (Thanks to M. Deinum) Change the CustomWebConfiguration.java like below;

@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("/**");
 }
}
like image 590
Rajkishan Swami Avatar asked Jul 23 '15 05:07

Rajkishan Swami


People also ask

Why Autowired is getting null?

If the application starts and your field appears to be null it is generally due to one of the following issues: Using @Autowired on a static field. Omitted @Autowired on a field. Instance of bean not visible to Spring.

What will happen if I make @autowired as false?

By default, the @Autowired annotation implies that the dependency is required. This means an exception will be thrown when a dependency is not resolved. You can override that default behavior using the (required=false) option with @Autowired .

What are the disadvantages of Autowired?

There are three weaknesses of autowiring : Overriding: You can still specify dependencies using <constructor-arg> and <property> settings which will always override @Autowired . Primitive data types: Autowiring can't be used to inject primitive and string values. It works with reference only.

Can you Autowire byType when multiple beans?

autowire byType - For this type of autowiring, class type is used. So there should be only one bean configured for this type in the spring bean configuration file. autowire by constructor - This is almost similar to autowire byType, the only difference is that constructor is used to inject the dependency.


1 Answers

Spring will only autowire beans it knows about, you are creating the instance yourself outside the control of Spring.

Either inject a CustomInterceptor into your configuration class or add a @Bean method to make it a Spring managed instance. Then use that instance to add it to the list of interceptors.

like image 70
M. Deinum Avatar answered Sep 23 '22 05:09

M. Deinum