springMvc笔记-Filter
作者:互联网
本笔记基于springBoot 2.3.3版本
一般我们平常如果要使用Filter,会用到如下代码。
@Configuration
@ConditionalOnClass(CoreFilter.class)
public class CoreFilterAutoConfiguration {
@Bean
public FilterRegistrationBean coreFilterAutoConfig() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new CoreFilter());
return bean;
}
}
图中我们可以看到,在CoreFilterAutoConfiguration配置类里我们定义一个@Bean注解,将码好的CoreFilter过滤器装入FilterRegistrationBean,最后注入到spring容器中去。
源码分析:
ServletContextInitializer
这个接口是spring提供的专门给Servlet,Filter,Lister组件使用的。我们看一下其集成UML图:
图中我们可以看到,上图分别是Filter,Servlet,Listener组件的spring类UML图。我们重点看第一张Filter图。通过上文我们知道,Filter是在StandardContext初始化阶段进行加载装入的。代码如下:
for (Map.Entry<ServletContainerInitializer, Set<Class<?>>> entry :
initializers.entrySet()) {
try {
1.entry.getKey().onStartup(entry.getValue(),
getServletContext());
} catch (ServletException e) {
log.error(sm.getString("standardContext.sciFail"), e);
ok = false;
break;
}
}
// Configure and call application event listeners
if (ok) {
2. if (!listenerStart()) {
log.error(sm.getString("standardContext.listenerFail"));
ok = false;
}
}
// Check constraints for uncovered HTTP methods
// Needs to be after SCIs and listeners as they may programmatically
// change constraints
if (ok) {
checkConstraintsForUncoveredMethods(findConstraints());
}
try {
// Start manager
Manager manager = getManager();
if (manager instanceof Lifecycle) {
((Lifecycle) manager).start();
}
} catch(Exception e) {
log.error(sm.getString("standardContext.managerFail"), e);
ok = false;
}
// Configure and call application filters
if (ok) {
3. if (!filterStart()) {
log.error(sm.getString("standardContext.filterFail"));
ok = false;
}
}
过滤器是在1处被加载的,具体如下代码:
private void selfInitialize(ServletContext servletContext) throws ServletException {
prepareWebApplicationContext(servletContext);
registerApplicationScope(servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}
selfInitialize会将从spring容器(或者叫spring应用上下文)里将ServletContextInitializer类型的Bean拿出来进行遍历执行其onStartUp方法。具体到FilterRegistrationBean方法执行顺序就是:
RegistrationBean.onStartUp -> DynamicRegistrationBean.register -> AbstractFilterRegistrationBean.addRegistration -> ApplicationContextFacade.addFilter -> ApplicationContext.addFilter -> StandardContext.addFilterDef -> filterDefs.put
RegistrationBean.onStartUp -> DynamicRegistrationBean.register -> AbstractFilterRegistrationBean.configure -> ApplicationFilterRegistration.addMappingForServletNames-> StandardContext.addFilterMap-> filterMaps.add
至此过滤器就已经添加到StandardContext的filterDefs属性当中去了,并同时将fiter相关信息也添加进filterMaps里
private Map<String, FilterDef> filterDefs = new HashMap<>();
private final ContextFilterMaps filterMaps = new ContextFilterMaps();
1方法之后开始执行3方法filterStart,这个方法将我们刚才添加入filterDefs里的filterDef转换成ApplicationFilterConfig 并放入fiterConfigs里,代码如下:
public boolean filterStart() {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Starting filters");
}
// Instantiate and record a FilterConfig for each defined filter
boolean ok = true;
synchronized (filterConfigs) {
filterConfigs.clear();
for (Entry<String,FilterDef> entry : filterDefs.entrySet()) {
String name = entry.getKey();
if (getLogger().isDebugEnabled()) {
getLogger().debug(" Starting filter '" + name + "'");
}
try {
ApplicationFilterConfig filterConfig =
new ApplicationFilterConfig(this, entry.getValue());
filterConfigs.put(name, filterConfig);
} catch (Throwable t) {
t = ExceptionUtils.unwrapInvocationTargetException(t);
ExceptionUtils.handleThrowable(t);
getLogger().error(sm.getString(
"standardContext.filterStart", name), t);
ok = false;
}
}
}
return ok;
}
当用户请求来时,调用链是TomcatWebServer.start -> Connector.start -> Connector.startInternal -> Http11NioProtocol.start -> NioEndpoint.start 这个方法里会创建服务器线程池,poller以及 acceptor线程。代码如下。
@Override
public void startInternal() throws Exception {
if (!running) {
running = true;
paused = false;
if (socketProperties.getProcessorCache() != 0) {
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getProcessorCache());
}
if (socketProperties.getEventCache() != 0) {
eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getEventCache());
}
if (socketProperties.getBufferPool() != 0) {
nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getBufferPool());
}
// Create worker collection
if (getExecutor() == null) {
createExecutor();
}
initializeConnectionLatch();
// Start poller thread
poller = new Poller();
Thread pollerThread = new Thread(poller, getName() + "-ClientPoller");
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
startAcceptorThread();
}
}
Accepter:用于接收socket连接,并将socket连接封装后,添加到Poller中去
Poller: 用于监听Socket事件,当Socket有读写事件时,将Socket封装下添加到Worker中线程任务队列中去
Worker(线程池里面的):拿到Poller传过来的socket连接后,对socket请求的预处理,包括分析报文并创建Request对象.再交给后续处理。流程图如下
方法流程是:Acceptor run方法-> poller.run -> poller. processKey-> AbstractEndpoint.processSocket -> 请求放入到线程池 -> SocketProcessor.doRun -> AbstractProtocol.process -> AbstractProcessorLight.process -> Http11Processor.service ->
CoyoteAdapter.service -> standEngineValve.invoke -> StandardContextValve.invoke -> StandardWrapperValve.invoke -> ApplicationFilterFactory.createFilterChain(该方法会将filterMaps,filterConfigs里的所有filter取出来和servlet组成调用链) ->
ApplicationFilterChain.doFilter -> ApplicationFilterChain.internalDoFilter(先执行所有filter,然后执行servlet的service方法,即DispathServlet) -> servlet.service 方法 -> 返回用户。
标签:socketProperties,ok,springMvc,笔记,Filter,start,new,SynchronizedStack,poller 来源: https://blog.csdn.net/Jarvan_Song/article/details/116595322