I've got a Spring Boot where I've autoconfigured a Router bean. This all works perfect but it becomes a problem when I want to inject that bean into a custom servlet:
public class MembraneServlet extends HttpServlet {
@Autowired
private Router router;
@Override
public void init() throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
new HttpServletHandler(req, resp, router.getTransport()).run();
}
}
This should be the way to go, but
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
won't autowire the Router because the WebapplicationContext
is always null. The application is running in an MVC environment.
Assuming you Spring Application Context is wired to the Servlet Context, you might want to pass ServletContext to SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
public class MembraneServlet extends HttpServlet {
@Autowired
private Router router;
@Override
public void init() throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this, getServletContext());
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
new HttpServletHandler(req, resp, router.getTransport()).run();
}
}
What about injecting 'Router' as constructor parameter.
So you would have this:
public class MembraneServlet extends HttpServlet {
private Router router;
public MembraneServlet(Router router){
this.router = router;
}
@Override
public void init() throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
new HttpServletHandler(req, resp, router.getTransport()).run();
}
}
then you can programatically create servlet registration like this:
@Bean
public ServletRegistrationBean membraneServletRegistrationBean(){
return new ServletRegistrationBean(new MembraneServlet(),"/*");
}
Embedded server
You can annotate with @WebServlet
your servlet class:
@WebServlet(urlPatterns = "/example")
public class ExampleServlet extends HttpServlet
And enable @ServletComponentScan
on base class:
@ServletComponentScan
@EntityScan(basePackageClasses = { ExampleApp.class, Jsr310JpaConverters.class })
@SpringBootApplication
public class ExampleApp
But injection with @ServletComponentScan will work only with embedded server:
Enables scanning for Servlet components (filters, servlets, and listeners). Scanning is only performed when using an embedded web server.
More info: The @ServletComponentScan Annotation in Spring Boot
External server
When using external server, mark HttpServlet
class as @Component
:
@Component
public class ExampleServlet extends HttpServlet
And create configuration class:
@Configuration
@ComponentScan(value = "com.example.servlet.package")
public class ServletConfig {
@Autowired
private ExampleServlet exampleServlet;
@Bean
public ServletRegistrationBean resetServletRegistrationBean(){
return new ServletRegistrationBean(exampleServlet, "/example");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With