对springbean的深入理解,源码调试分析

本文深入探讨了Spring MVC框架中控制器(Controller)方法映射的实现原理,详细讲解了如何通过注解如@Controller和@RequestMapping来标记类和方法,使它们能够响应特定的HTTP请求。此外,还分析了beanFactory在注册bean过程中的作用,以及bean后置处理器如何影响bean的创建和初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何映射controller?
如何映射静态页面?

直接定位到注册bean工厂

在这里插入图片描述

静态类方法注入
在这里插入图片描述

且看beanFactory

在这里插入图片描述
bean工厂获取bean的后置处理器
在这里插入图片描述
其实这几个都在beanFactory中
在这里插入图片描述
bean的后置处理器
在这里插入图片描述
spring做了一个先删除 后添加的操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述



public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {


   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);


   // Register BeanPostProcessorChecker that logs an info message when
   // a bean is created during BeanPostProcessor instantiation, i.e. when
   // a bean is not eligible for getting processed by all BeanPostProcessors.
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));


   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
   List<String> orderedPostProcessorNames = new ArrayList<String>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<String>();


   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }


   // First, register the BeanPostProcessors that implement PriorityOrdered.
   sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);


   // Next, register the BeanPostProcessors that implement Ordered.
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   sortPostProcessors(beanFactory, orderedPostProcessors);
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);


   // Now, register all regular BeanPostProcessors.   【开始注入bean】
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);


   // Finally, re-register all internal BeanPostProcessors.
   sortPostProcessors(beanFactory, internalPostProcessors);
   registerBeanPostProcessors(beanFactory, internalPostProcessors);


   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}


讨论一下,controller层中的方法映射是如何被扫码发现且打印出来的?

比如这样

10:19:33.108 [RMI TCP Connection(3)-127.0.0.1] INFO  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/article/create],methods=[GET]}" onto public java.lang.String com.wangzhixuan.controller.ArticleController.create()
10:19:35.036 [RMI TCP Connection(3)-127.0.0.1] INFO  org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/article/save],methods=[POST]}" onto public com.wangzhixuan.commons.result.Result com.wangzhixuan.controller.ArticleController.save(java.lang.String)

调试如下:
在这里插入图片描述
在这里插入图片描述

如何区分不同的bean ?

if (beanType != null && isHandler(beanType)) {
   detectHandlerMethods(beanName);
}

在这里插入图片描述
其实就是判断某个类上是否有Controller或者 RequestMapping注解 卧槽
在这里插入图片描述

然后再去查询增强控制层接口的类

在这里插入图片描述
源码如下:


private void initControllerAdviceCache() {
   if (getApplicationContext() == null) {
      return;
   }
   if (logger.isInfoEnabled()) {
      logger.info("Looking for @ControllerAdvice: " + getApplicationContext());
   }


   List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
   AnnotationAwareOrderComparator.sort(beans);


   List<Object> requestResponseBodyAdviceBeans = new ArrayList<Object>();


   for (ControllerAdviceBean bean : beans) {
      Set<Method> attrMethods = MethodIntrospector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS);
      if (!attrMethods.isEmpty()) {
         this.modelAttributeAdviceCache.put(bean, attrMethods);
         if (logger.isInfoEnabled()) {
            logger.info("Detected @ModelAttribute methods in " + bean);
         }
      }
      Set<Method> binderMethods = MethodIntrospector.selectMethods(bean.getBeanType(), INIT_BINDER_METHODS);
      if (!binderMethods.isEmpty()) {
         this.initBinderAdviceCache.put(bean, binderMethods);
         if (logger.isInfoEnabled()) {
            logger.info("Detected @InitBinder methods in " + bean);
         }
      }
      if (RequestBodyAdvice.class.isAssignableFrom(bean.getBeanType())) {
         requestResponseBodyAdviceBeans.add(bean);
         if (logger.isInfoEnabled()) {
            logger.info("Detected RequestBodyAdvice bean in " + bean);
         }
      }
      if (ResponseBodyAdvice.class.isAssignableFrom(bean.getBeanType())) {
         requestResponseBodyAdviceBeans.add(bean);
         if (logger.isInfoEnabled()) {
            logger.info("Detected ResponseBodyAdvice bean in " + bean);
         }
      }
   }


   if (!requestResponseBodyAdviceBeans.isEmpty()) {
      this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
   }
}

全局异常处理
在这里插入图片描述
配置静态路径
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值