Tomcat的系统架构与设计模式
Tomcat总体结构
conf/server.xml配置文件:
Tomcat的心脏即为Connector和Container组件:
1
2 往外层看,一个Container对应多个Connector(如图有http和ajp等不同的Connetctor,Connector负责对外交流,接收请求,Container处理Connector接受的请求),它们共同组成一个Service,而多个Service就组成一个Server;
往里层看,Container含有Engine(Servlet引擎),Engine含有Host(虚拟主机),Host含有Context(一个Context对应一个Web应用),Context含有Wrapper(一个Wrapper对应一个Servlet)。
Service类的实现类为StandardService
类。由于Service中,Container只有一个,Connector可多个,因此,StandardService提供setContainer()
方法用于设置Container(具体实现:去掉老Container与Service的关系,添加新Container与Service的关系,并一一添加Connector与新Containner的关系),以及addConnector()/removeConnector()
方法用于添加/删除Connector(具体实现:在StandardService类中维护的connectors数组中增减Connector)。
Server类的实现类为StandardServer
类。Server中可有多个Service,因此,StandardServer同样提供addService()/removeService()
方法来增减Service,以及findService()
来供外部找到相应的Service。
Connector组件
Connector负责接收浏览器发过来的TCP连接请求,创建org.apache.coyote.Request
和org.apache.coyote.Response
用于交换数据,之后Container会创建一个新的线程,并接收到传来的Request和Response对象,重新创建org.apache.catalina.connector.Request
和org.apache.catalina.connector.Response
对象,进行后续处理。
Container组件
Container使用了经典的责任链模式,即从Engine到Warpper,层层关联。Engine作为顶层,不能调用setParent()
方法再设置父容器,但可以调用addChild()
方法添加子容器(且子容器只能是host);Wrapper作为最底层容器,也不能调用addChild()
方法添加子容器,但可以调用setParent()
方法设置父容器(且父容器只能是context)。
简单的tomcat可以没有Engine和Host。
Spring框架的设计理念与设计模式分析
核心组件
- Spring的核心组件即:Bean、Context、Core;
- 三者的形象比喻即:Bean是演员,Context是舞台背景,Core是演出的道具。
- Bean即是Object的包装,Context就是要发现每个Bean之间的关系,为他们建立好并维护这个关系,所以Context就是Bean关系的集合,这个关系集合又叫Ioc容器。而Core就是发现、建立、维护关系所需要的一系列工具,把Core组件看成Util更容易理解。
Spring Bean的创建是典型的工厂模式,顶级接口即BeanFactory,有三个子类,分别是:ListableBeanFactory
(表明bean是可列表的)、HierarchicalBeanFactory
(表明Bean是有继承关系的,即每个Bean可能有父Bean)、AutowireCapableBeanFactory
(定义Bean的自动装配规则),以上四个接口共同定义了Bean的集合、关系和行为。
Bean的完整定义在配置文件的<bean/>
节点。当Spring成功解析一个Bean节点时,在spring的内部就会转化为一个BeanDefnition对象,以后所有的操作都是在这个对象上进行的。
Ioc容器如何工作
如何创建BeanFactory
Ioc容器实际上是COntext组件结合其他两个组件共同构建的一个Bean关系网。构建的入口即是AbstractApplicationContext类的refresh()
。
更新BeanFactory,首先就是如果BeanFactory已存在就更新,否则就创建,而更新的代码是,如果存在就destroyBeans()
并closeBeanFactory()
,然后createBeanFactory()
,创建的原始对象即是DefaultListableBeanFactory。并且后面会调用loadBeanDefinitions(beanFactory)
。前文说到Spring内部Bean被转化为一个BeanDefnition对象,该方法即是加载、解析Bean的定义。
Ioc的扩展点
构建入口refresh()
的实现代码处,有这样两句关键代码,体现了Spring的扩展点:1
2
3
4//初始化和执行BeanFactoryPostProcessor beans
invokeBeanFactoryPostProcessors(beanFactory);
//初始化和执行BeanPostProcessor beans
registerBeanPostProcessors(beanFactory);
第二句代码主要是获取实现BeanFactoryPostProcessor接口的子类,并执行它的postProcessBeanFactory()
方法,该方法顾名思义即是调用BeanFactory新增加工器,即当BeanFactory创建时被调用。这个方法参数需要传入一个beanFactory(实际是ConfigurableListableBeanFactory,表示可配置的BeanFactory),说明可以对beanFactory做修改。
第四句代码,方法顾名思义是注册Bean新增加工器,即该方法也是获取实现了BeanPostProcessor接口的子类,并把它们(Bean新增加工器)注册到BeanFactory对象的beanPostProcessors变量中。BeanPostProcessor接口定义了两个方法:postProcessBeforeInitialization()
和postProcessAfterInitialization()
,每当bean对象初始化时,进行相关调用,执行用户自定义的操作。
另外一个就是FactoryBean,这是一个工厂Bean,一个可以产生Bean的Bean。如果一个类继承FactoryBean,用户可以自己定义产生实例对象的方法,只需实现它的getObject()
方法即可。
由上,Spring的Ioc容器的扩展点主要有:
- BeanFactoryPostProcessor:构建BeanFactory时调用;
- BeanPostProcessor:构建Bean时调用;
- InitializingBean、DisposableBean:Bean实例创建和销毁时调用;
- FactroyBean:可让你创建自定义的对象,可实现更多的控制。
Spring中AOP的特性详解
AOP即通过上面的FactoryBean来进行扩展来完成这个特性的。代理类继承了FactoryBean的ProxyFactoryBean。
设计模式解析之代理模式
即给某一个对象创建一个代理对象,由这个代理对象控制对原对象的引用,代理对象可在调用原对象时增加一些额外操作。
Spring MVC的工作机制与设计模式
整体介绍
SpringMVC的嵌入关键就是通过配置Web.xml的servlet,核心类即DispatcherServlet,它继承了HttpServlet,在Servlet的init方法调用时DispatcherServlet执行SpringMVC的初始化工作。具体初始化:
- initMultipartResolver:用于文件上传服务;
- initLocalResolver:用于处理应用的国际化;
- initThemeResolver:用于定义一个主题;
- initHandlerMappings:用于定义用户设置的请求映射关系;
核心组件
- initHandelrAdapters:用于根据Handler的类型定义不同的处理规则;
核心组件
- initHandlerExceptionResolvers:当Handler处理出错时,会通过这个Handler统一处理;
- initRequestToViewTranslator:将指定的ViewName按照定义的RequestToViewNameTranslator替换成想要的格式(如加上前缀、后缀);
- initViewResolvers:用于将View解析成页面。
核心组件
Control设计
Control=HandlerMapping+HandlerAdapters
HandlerMapping
HandlerMapping负责帮助我们管理URL和对应处理类(Handler)的映射关系,就是将一个或多个URL映射到一个或多个Spring Bean中。
它的初始化工作完成的两个最重要的工作就是:将URL与Handler的对应关系保存在handlerMap集合中,并将所有的interceptors对象保存在adaptedInterceptors数组中。
HandlerAdapter
HandlerAdapter用于帮助自定义各种Handler。一般的MVC框架会先定义一个特定接口,让Handler去实现,然后MVC框架通过调用接口方法来调用Handler。而SpringMVC此处使用了多接口(如有:HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、SimpleServletHandlerAdapter等),不同接口定义不同方法,然后让Handler去选择实现这些个接口,让Handelr的实现更加灵活。
它的初始化工作即是创建一个HandlerAdapter对象,将这个HandlerAdapter对象保存在DispatcherServlet的handlerAdapters集合中。
整体调用逻辑
1 | URL到来时,DispatcherServlet执行`doDispatch()`方法。 |
Model设计
在业务逻辑层通常也有Model实例,不过此处所谓的Model,是指针对模版渲染的Model(ModelAndView)。
ModelAndView对象是连接业务逻辑层与View表现层的桥梁,对SpringMVC来说它也是连接Handler与View的桥梁。
Model顾名思义即会持有一个ModelMap对象和一个View对象(或View名称)。在Handler中,将模板中需要的对象会存在这个ModelMap中,然后传递到View对应的ViewResolvers中,不同的ViewResovler对这个ModelMap中的对象有不同的处理方式。
View设计
View=RequestToViewNameTranslator+ViewResolver
RequestToViewNameTranslator用来支持用户自定义对ViewName的解析,如给请求的ViewName加上前缀或后缀,或替换成特定的字符等。
ViewResolver则是根据ViewName创建View对象。
设计模式解析之模板模式
核心即是:大的逻辑已经定义,要做的就是实现一些具体步骤。
SpringMVC的View设计使用了模板模式,View只定义了接口方法,AbstractView类实现了在View中定义的所有方法,并留有一个抽象方法renderMergedOutputModel给子类去实现。而子类AbstractJasperReportsView和AbstractTeamplateView抽象类实现了上述留有的方法,并进一步细化出了renderReport抽象方法和renderMergedTemplateModel方法给子类去进一步实现。
深入分析iBatis框架之系统架构与映射原理
左边的SqlMapClient接口主要定义了客户端的操作行为,包括select、insert、update和delete。而邮编主要定义了当前客户端在当前线程中的执行环境。SqlMapSession可以共享使用,也可以自己创建,如果自己创建,需要在结束时自行关闭。
iBatis通过解析SqlMap配置文件得到所有的Statement执行语句,同时会形成ParameterMap、ResultMap和SQL。当iBatis构建好RequestScope执行环境后,要做的工作就是把传过来的对象数据结合ParameterMap中的信息提取出一个参数数组,这个数组的顺序对应与SQL中参数的顺序,然后调用preparedStatement.setXXX(i,parameter)提交参数。
iBatis可以自己管理事务,也可以由外部管理。iBatis自己管理是通过共享SqlMapSession对象实现的,多个Statement执行时共享一个SqlMapSession实例,而且线程安全。如果外部程序管理就要自行控制SqlMapSession对象的生命周期。
设计模式解析之简单工厂模式
核心即:通过判断其条件,来返回不同的对象实例
iBatis中的DataExchangeFactory即使用了简单工厂模式,它是一个工厂,它可根据传递进来的不同class类型返回不同的对象产品,这里返回的产品都是单例,当然简单工厂模式也可以每次创建一个新对象返回给调用者。
设计模式解析之工厂模式
与简单工厂模式不同的是,这里就不再是一个工厂,而是多个工厂,与一个顶层抽象工厂。如果把服务器单机比作简单工厂模式的工厂,那么服务器集群+一个负载均衡服务器就是工厂模式的多个工厂和顶层抽象工厂。
在iBatis中的DataSourceFacotry就是抽象工厂类,对应的JndiDataSourceFactory和DbcpDataSourceFactory就是具体工厂。
更多文章,请关注:开猿笔记