首页 / SERVLET / 解析源码---结合@ServletComponentScan与@WebServlet,@WebFilter,@WebListener注册servlet,filter,listener
解析源码---结合@ServletComponentScan与@WebServlet,@WebFilter,@WebListener注册servlet,filter,listener
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了解析源码---结合@ServletComponentScan与@WebServlet,@WebFilter,@WebListener注册servlet,filter,listener,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6974字,纯文字阅读大概需要10分钟。
内容图文
![解析源码---结合@ServletComponentScan与@WebServlet,@WebFilter,@WebListener注册servlet,filter,listener](/upload/InfoBanner/zyjiaocheng/736/7b8146825db544f0b39dbcbdf21f3c65.jpg)
概述
由于@ServletComponentScan所在类被加载BeanDefinition时,会加载其Registar。所以会导入ServletComponentScanRegistrar,由此向beanfactory添加了一个ServletComponentRegisteringPostProcessor。当最后调用各种nonOrderedPostProcessors时,会调用ServletComponentRegisteringPostProcessor的postProcessBeanFactory,最终扫描路径获取由@WebServlet,@WebFilter,@WebListener注册的servlet,filter,listener。
前言
我们可以看见@ServletComponentScan import 了ServletComponentScanRegistrar
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ServletComponentScanRegistrar.class)
public @interface ServletComponentScan {
......
}
而ServletComponentScanRegistrar向beanfactory添加了ServletComponentRegisteringPostProcessor
class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
......
private void addPostProcessor(BeanDefinitionRegistry registry,
Set<String> packagesToScan) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(ServletComponentRegisteringPostProcessor.class);
beanDefinition.getConstructorArgumentValues()
.addGenericArgumentValue(packagesToScan);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
}
......
}
入口
通过@ServletComponentScan所在组件类加载BeanDefinition时,加载ServletComponentScanRegistrar
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
......
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//加载ServletComponentScanRegistrar
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
然后调用ServletComponentScanRegistrar的registerBeanDefinitions:向BeanDefinitionRegistry添加ServletComponentRegisteringPostProcessor
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
//根据注解所在类的元信息获取扫描包路径,如果没有定义注解扫描的包路径,就以注解所在类的包路径为默认路径
Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
//是否已有ServletComponentRegisteringPostProcessor,无则添加,有则更新
if (registry.containsBeanDefinition(BEAN_NAME)) {
updatePostProcessor(registry, packagesToScan);
}
else {
addPostProcessor(registry, packagesToScan);
}
}
执行
AbstractApplicationContext:其中refresh方法会调用各个后处理器
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
......
// 调用各个后处理器,添加各种beandefinition
invokeBeanFactoryPostProcessors(beanFactory);
......
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors:
统一处理各种BeanFactoryPostProcessor,最后一种BeanFactoryPostProcessor处理就是有关ServletComponentRegisteringPostProcessor处理servlet,filter,listener
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
......
//添加各类bean
}
......
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//调用ServletComponentRegisteringPostProcessor处理servlet,filter,listener
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
......
}
ServletComponentRegisteringPostProcessor
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
//必须是嵌入式的tomcat并且此时ServletContext为null
if (isRunningInEmbeddedWebServer()) {
//获取环境和ResourceLoader,及确定需要扫描@WebServlet,@WebFilter,@WebListener
ClassPathScanningCandidateComponentProvider componentProvider = createComponentProvider();
//packagesToScan是@ServletComponentScan的扫描路径
for (String packageToScan : this.packagesToScan) {
scanPackage(componentProvider, packageToScan);
}
}
}
private void scanPackage(
ClassPathScanningCandidateComponentProvider componentProvider,
String packageToScan) {
//获取包路径下有@WebServlet,@WebFilter,@WebListener的类
for (BeanDefinition candidate : componentProvider
.findCandidateComponents(packageToScan)) {
if (candidate instanceof ScannedGenericBeanDefinition) {
for (ServletComponentHandler handler : HANDLERS) {
handler.handle(((ScannedGenericBeanDefinition) candidate),
(BeanDefinitionRegistry) this.applicationContext);
}
}
}
}
WebServletHandler.doHandle:最终添加Servlet的BeanDefinition
@Override
public void doHandle(Map<String, Object> attributes,
ScannedGenericBeanDefinition beanDefinition,
BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.rootBeanDefinition(ServletRegistrationBean.class);
builder.addPropertyValue("asyncSupported", attributes.get("asyncSupported"));
builder.addPropertyValue("initParameters", extractInitParameters(attributes));
builder.addPropertyValue("loadOnStartup", attributes.get("loadOnStartup"));
String name = determineName(attributes, beanDefinition);
builder.addPropertyValue("name", name);
builder.addPropertyValue("servlet", beanDefinition);
builder.addPropertyValue("urlMappings", extractUrlPatterns(attributes));
builder.addPropertyValue("multipartConfig",
determineMultipartConfig(beanDefinition));
//注册BeanDefinition
registry.registerBeanDefinition(name, builder.getBeanDefinition());
}
WebFilterHandler:最终添加合法的filter的BeanDefinition
@Override
public void doHandle(Map<String, Object> attributes,
ScannedGenericBeanDefinition beanDefinition,
BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.rootBeanDefinition(FilterRegistrationBean.class);
builder.addPropertyValue("asyncSupported", attributes.get("asyncSupported"));
builder.addPropertyValue("dispatcherTypes", extractDispatcherTypes(attributes));
builder.addPropertyValue("filter", beanDefinition);
builder.addPropertyValue("initParameters", extractInitParameters(attributes));
String name = determineName(attributes, beanDefinition);
builder.addPropertyValue("name", name);
builder.addPropertyValue("servletNames", attributes.get("servletNames"));
builder.addPropertyValue("urlPatterns", extractUrlPatterns(attributes));
//注册BeanDefinition
registry.registerBeanDefinition(name, builder.getBeanDefinition());
}
对于Listener处理差不多,通过WebListenerHandler.doHandle()
@Override
protected void doHandle(Map<String, Object> attributes,
ScannedGenericBeanDefinition beanDefinition,
BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.rootBeanDefinition(ServletListenerRegistrationBean.class);
builder.addPropertyValue("listener", beanDefinition);
//注册BeanDefinition
registry.registerBeanDefinition(beanDefinition.getBeanClassName(),
builder.getBeanDefinition());
}
内容总结
以上是互联网集市为您收集整理的解析源码---结合@ServletComponentScan与@WebServlet,@WebFilter,@WebListener注册servlet,filter,listener全部内容,希望文章能够帮你解决解析源码---结合@ServletComponentScan与@WebServlet,@WebFilter,@WebListener注册servlet,filter,listener所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。