欢迎来到皮皮网网首页

【山西离广州源码】【辅助之神的源码】【成绩共享android源码】autowired 源码解析

来源:动软.net系统框架 源码 时间:2024-11-24 16:12:40

1.spring的码解编写流程(spring流程编排)
2.我找到了Dubbo源码的BUG,同事纷纷说我有点东西

autowired 源码解析

spring的码解编写流程(spring流程编排)

       springmvc工作流程

       springmvc工作流程:

       1、用户向服务端发送一次请求,码解这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。码解

       2、码解DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。码解山西离广州源码由此得知,码解该请求该由哪个Controller来处理(并未调用Controller,码解只是码解得知)。

       3、码解DispatcherServlet调用HandlerAdapter处理器适配器,码解告诉处理器适配器应该要去执行哪个Controller。码解

       4、码解HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),码解并层层返回给DispatcherServlet。码解

       5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,辅助之神的源码然后返回真正的视图。

       6、DispatcherServlet将模型数据填充到视图中。

       7、DispatcherServlet将结果响应给用户。

       组件说明:

       DispatcherServlet:前端控制器,也称为中央控制器,它是整个请求响应的控制中心,组件的调用由它统一调度。

       HandlerMapping:处理器映射器,它根据用户访问的URL映射到对应的后端处理器Handler。也就是说它知道处理用户请求的后端处理器,但是它并不执行后端处理器,而是将处理器告诉给中央处理器。

       HandlerAdapter:处理器适配器,它调用后端处理器中的成绩共享android源码方法,返回逻辑视图ModelAndView对象。

       ViewResolver:视图解析器,将ModelAndView逻辑视图解析为具体的视图(如JSP)。

       Handler:后端处理器,对用户具体请求进行处理,也就是我们编写的Controller类。

       spring工作流程

       写得太笼统了,不过,spring+hibernate得基本工作流是分层得.

       也许是:

       reg页面是前台表单录入视图,提交后到RegController控制器,然后其中又封装了User和Reg得vo对象,在RegController中调用UserDAOImpl和RegImpl执行数据得保存,UserDAO是接口,UserDAOImpl实现了此接口.UserDAOImpl和RegImpl使用hibernate能力进行ROM映射,保存对象到数据库.regsuccess是保存数据成功后得返回视图.

       spirngmvc需要配置控制器映射,将访问映射到控制器上,控制器调用dao或是services层得api执行业务逻辑,然后返回视图和模型对象给前置控制器,前置控制器根据返回得信息派发视图.

Spring启动流程(一)

       以java-config形式编写一个测试demo,新建一个AnnotationConfigApplicationContext,如果是XML形式使用ClassPathXmlApplicationContext;

       两者都继承了AbstractApplicationContext类,详细看下面的层次图。

       注意:在newAnnotationConfigApplicationContext()时如果未指定参数,会报运行时异常:org.springframework.context.annotation.AnnotationConfigApplicationContext@6ebca6hasnotbeenrefreshedyet

       AnnotationConfigApplicationContext的有参构造执行了3个方法,分别是自己的无参构造、register()、refresh();

       在描述前先从网上找了一个总体流程图方便了解一下大致流程,理清思路。外汇通源码

       在执行AnnotationConfigApplicationContext的无参构造方法前会调用父类GenericApplicationContext的无参构造方法;

       GenericApplicationContext中实例化一个DefaultListableBeanFactory,也就是说bean工厂实际上是应用上下文的一个属性;

       从上面的类层次图可以看到:应用上下文和bean工厂又同时实现了BeanFactory接口。

       前面讲到我们为了解IOC使用了Spring提供的AnnotationConfigApplicationContext作为入口展开,那Spring怎么对加了特定注解(如@Service、@Repository)的类进行读取转化成BeanDefinition对象呢?

       又如何对指定的包目录进行扫描查找bean对象呢?

       所以我们需要new一个注解配置读取器和一个路径扫描器。

       AnnotatedBeanDefinitionReader中执行了AnnotationConfigUtils中的registerAnnotationConfigProcessors(this.registry)方法,会向容器注册Sprign内置的处理器。

       registerAnnotationConfigProcessors方法中通过newRootBeanDefinition(XX.class)新建一个RootBeanDefinition(BeanDefinition的一个实现),然后调用registerPostProcessor将内置bean对应的BeanDefinition保存到bean工厂中;

       这里需要说明的是:我们刚刚一直在谈到注册bean,实际上就是将内置bean对应的beanDefinition保存到bean工厂中。那为什么要保存beanDefinition呢?因为Spring是跟据beanDefinition中对bean的描述,来实例化对象的,就算自己定义的bean也是要被解析成一个beanDefinition并注册的。

       其中最主要的组件便是ConfigurationClassPostProcessor和AutowiredAnnotationBeanPostProcessor,前者是一个beanFactory后置处理器,用来完成bean的智慧城市游戏 源码扫描与注入工作,后者是一个bean后置处理器,用来完成@AutoWired自动注入。

       这个步骤主要是用来解析用户传入的Spring配置类,解析成一个BeanDefinition然后注册到容器中,主要源码如下:

       通过生成AnnotatedGenericBeanDefinition,然后解析给BeanDefinition的其他属性赋值,然后将BeanDefinition和beanName封装成一个BeanDefinitionHolder对象注册到bean工厂中(就是将beanName与baenDefinition封装到Map中,将beanName放到list中。Map与list都是bean工厂DefaultListableBeanFactory所维护的属性),和前面内置bean的注册相同。

       执行到这一步,register方法到此就结束了,通过断点观察BeanFactory中的beanDefinitionMap属性可以看出:this()和this.register(componentClasses)方法中就是将内置bean和我们传的配置bean的beanDefinition进行了注册,还没处理标记了@Component等注解的自定义bean。

我找到了Dubbo源码的BUG,同事纷纷说我有点东西

       某天,运营反馈称,执行一次保存操作后,后台出现3条数据,我立刻怀疑可能存在代码问题。为了确保不会误判,我要求暂停操作,保留现场,以便我进行排查。

       查看新增代码,发现是同事三歪进行的改动,他将原有的dubbo XML配置方式改为了注解方式。我询问其改动详情,得知他是更改了模块的配置方式。于是,我决定深入研究,找出问题所在。

       dubbo配置方式多样,最常见的为XML配置与注解配置。我已初步推测原因,接下来将进行详细的调试过程。

       我使用dubbo版本2.6.2进行调试。首先,针对采用@Reference注解条件下的重试次数配置,我发现调用接口时,会跳转到InvokerInvocationHandler的invoke方法。继续跟踪,最终定位到FailoverClusterInvoker的doInvoke方法。在该方法中,我关注到获取配置的retries值,发现其默认值为null,导致最终计算出的重试次数为3。

       采用dubbo:reference标签配置重试次数时,同样在获取属性值后,发现其默认值为0,与注解配置一致,最终计算出的重试次数为1。对比两种配置方式,我总结了以下原因:

       在@Reference注解形式下,dubbo会在注入代理对象时,通过自定义驱动器ReferenceAnnotationBeanPostProcessor来注入属性。在标签形式下,虽然也使用了Autowired注解,但dubbo会使用自定义名称空间解析器DubboNamespaceHandler进行解析。

       在注解形式下,当配置retries为0时,属性值在注入过程中并未被解析为null,但进入buildReferenceBean时,因nullSafeEquals方法的处理,导致默认值和实际值不一致,最终未保存到map中。而标签形式下,解析器能够正确解析出retries的值为0,避免了后续的问题。

       总结发现,采用@Reference注解配置重试次数时,dubbo在注入属性过程中存在逻辑处理上的问题,导致默认值与实际值不一致。此为dubbo的一个逻辑bug。建议在不需要重试时,设置retries为-1,以确保接口的幂等性。需要重试时,设置为1或更大值。

       问题解决后,我优化了文件操作,将其改为异步处理,从而缩短了主流程的时间。最终,数据出现3条的状况得以解决。

       此问题已得到解决,并在后续dubbo版本2.7.3中修复,确保了在注解配置方式下,nullSafeEquals方法能够正确处理默认值与实际值一致的情况。