我们要将一个Filter加入到tomcat中,写一个如下的配置
@Configuration
public class WebConfiguration {
@Bean
public FilterRegistrationBean testFilterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new OAuth2SSOFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("KcOAuth2SSOFilter");
registrationBean.setOrder(1);
return registrationBean;
}
}
如上面的代码,将我们需要的filter设置到FilterRegistrationBean中,然后将FilterRegistrationBean放入spring容器。那么原理是什么?
ServletWebServerApplicationContext
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
// 我们以使用外部tomcat启动为例:
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
// 使用内部tomcat执行
if (webServer == null && servletContext == null) {
// ...
this.webServer = factory.getWebServer(getSelfInitializer());
// ...
}
// 使用外部tomcat方式启动执行
else if (servletContext != null) {
try {
// 获取spring中ServletContextInitializer接口的实现类,并调用其onStartup方法
// 在onStartup方法中,会调用子类FilterRegistrationBean的getFilter方法并设置到
// tomcat上下文ServletContext中
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
private ServletContextInitializer getSelfInitializer() {
return this::selfInitialize;
}
private void selfInitialize(ServletContext servletContext) throws ServletException {
prepareWebApplicationContext(servletContext);
registerApplicationScope(servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}