【JAVA高级学习】SSM框架整合和核心要点【1】

SpingIoc和AOP底层原理

IoC

1. 控制反转(Inversion of Control)也称依赖注入(Dependency Injection),是一个定义对象依赖的过程。对象只和构造参数、工厂方法参数、对象实例属性或工厂方法返回相关。容器在创建这些bean时注入这些依赖。(简单来说和“new”关键字无关。)这个过程是一个反向的过程。(不是通过程序员编码实现正向注入,而是容器来管理这些过程)。对象实例的创建由其提供的构造方法或服务定位机制来实现。(服务定位机制:工厂方法)
2. IoC最大的好处:解耦
3. 容器初始化流程:ApplicationContext容器初始化主要由AbstractApplicationContext类中的refresh方法实现。大致过程如下:
	3.1 在spring中构建容器的过程都是同步的。同步操作是为了保证容器构建过程中,不出现多线程资源冲突。

在这里插入图片描述

	3.2 prepareRefresh():上线文预加载,简单了理解成:解析配置文件的过程。
	3.3 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():BeanFactory的构建:BeanFactory是ApplicationContext的父接口。是Spring框架中顶级容器工厂对象。BeanFactroy只能管理bean对象,没有其他功能,比如:aop切面管理,propertyplaceholder的加载等。构建BeanFactory的目的就是管理bean对象
	3.4 prepareBeanFactory(beanFactory):创建BeanFactory中管理的bean对象
	3.5 postProcessBeanFactory(beanFactory):加载配置中BeanFactory中无法处理的内容,比如:propertyplaceholder的加载。
	3.6 invokeBeanFactoryPostProcessors(beanFactory):将上一步加载的内容,作为一个容器可以管理的bean对象注册到Applicationcontext中。底层实质是在将postProcessBeanFactory中加载的内容包装成一个容器ApplicationContext可以管理的对象。
	3.7 registerBeanPostProcessors(beanFactory):继续完成上一步操作。为bean注册拦截处理器(AOP相关),到此:配置文件中配置的bean对象都创建并注册完成。
	3.8 initMessageSource():i18n国际化,初始化国际化消息源
	3.9 initApplicationEventMulticaster():初始化多播事件(处理事件监听,如ApplicationEvent等)。是Spring框架中的观察者模式实现机制。
	3.10 onRefresh():初始化主题(ThemeSource)。Spring 框架提供的视图主题信息。
	3.11 registerListeners():注册自定义监听器
	3.12 finishBeanFactoryInitialization(beanFactory):实例化所有非lazy-init 的singleton 实例。
	3.13 finishRefresh():最后一步。发布最终事件。生命周期监听事件。Spring 容器定义了生命周期接口(Lifecycle 接口)。可以实现容器启动调用初始化,容器销毁之前调用回收资源。

多容器/父子容器

Spring框架允许在一个应用中创建多个上下文容器。但是建议容器之间有父子关系,可以通过ConfigurableApplilcationContext接口定义的setParent方法设置父容器。一旦设置了父子关系,则可以通过子容器获取父容器除PropertyPlaceHolder以外的所有资源,父容器不能获取子容器中的任意资源(类似Java中类的继承)。
1. 典型的父子容器:spring和springmvc同时使用时。ContextLoaderListener创建的容器是父容器,DispatcherServlet创建的容器是子容器。
2. 目的:保证一个JVM中,只有一个树状结构的容器树。可以通过子容器访问父容器。

p域/c域

Spring2.0 之后引入了p域,Spring3.1zhi'hou引入了c域。可以简化配置文件中对property和constructor-arg的配置
<bean id="oneBean" class="com.sxt.OneBean"
p:a="10"
p:o-ref="otherBean"
c:a="20"
c:o-ref="otherBean"/>

lookup-method

1.lookup-method一旦应用,Spring框架会自动使用CGLIB技术为指定类型创建一个动态子类型,并自动实现抽象方法。可以动态的实现依赖注入的数据准备。
2. 在效率上,比直接自定义子类型慢。相对来说更加通用。可以只提供lookup-method的方法的 返回值对象即可实现动态的对象返回。
3. 在工厂方法难以定制的时候使用。也是模板的一种应用,工厂方法的扩展。
4. 如:工厂方法返回对象类型为接口类型。且不同版本应用返回的对象未必相同时使用。可以避免多次开发工厂类
5.实现如下:
<bean id="manager" class="com.sxt.lookupmethod.CommandManager">
	<lookup-method bean="command2" name="createCommand"/>
</bean>
<bean id="command1" class="com.sxt.lookupmethod.MyCommand1"></bean>
<bean id="command2" class="com.sxt.lookupmethod.MyCommand2"></bean>
public class TestLookupMethod {
	public static void main(String[] args) {
		ApplicationContext context = 
				new ClassPathXmlApplicationContext("classpath:lookupmethod/applicationContext.xml");
		
		CommandManager manager = context.getBean("manager", CommandManager.class);
		
		System.out.println(manager.getClass().getName());
		manager.process();
	}
}

abstract class CommandManager{
	public void process() {
		MyCommand command = createCommand();
        // do something ...
		System.out.println(command);
    }

    protected abstract MyCommand createCommand();
}
interface MyCommand{
}
class MyCommand1 implements MyCommand{
	public MyCommand1(){
		System.out.println("MyCommand1 instanced");
	}
}
class MyCommand2 implements MyCommand{
	public MyCommand2(){
		System.out.println("MyCommand2 instanced");
	}
}

Spring Aop底层执行流程图(jdk动态代理)

在这里插入图片描述

AOP中常用的Pointcut-expression

AOP开发中,有几个非常重要的概念,其中有一个概念叫“切点”。代表通知切入到代码执行流程的那个位置点。
切点一般通过表达式定义。Spring框架会通过SpringEL来解析表达式。表达式有多种定义方式。分别对应不同的解析结果。

execution表达式

语法格式:execution(返回类型 包名.类名.方法名(参数表))
如:execution(java.lang.String com.xxx.service.AService.test(java.lang.Integer))
说明:在类型com.xxx.service.AService中有方法test,且参数为Integer,返回值类型为String时增加切面
如:execution(* com.xxx.AService.*(..))
说明:在com.xxx.AService类型中任意方法、任意参数类型以及任意返回值类型,都增加切面。
应用:最常用的配置。根据方法执行的标准,定义切点。如:事务处理,日志处理等

target表达式

以目标对象作为切点的表达式定义方式。
语法:target(包名.接口名)
如:target(com.xxx.IA)
说明:所有实现了IA接口的实现类,作为代理的目标对象,会自动增加通知的织入,实现切面。
应用:为某一个具体的接口实现提供的配置。如:登录。登录的时候需要执行的附属逻辑是比较多的。在不同的业务流程中,附属逻辑也不同。如:电商中,可能在登录的时候,需要去执行购物车合并。(例如:登录前后的购物车信息在后置通知中实现)

this表达式

实现了某接口的代理对象,会作为切点。和target很类似
语法:this(包名.接口名)
如:this(com.xxx.IA)
说明:代理对象如果实现了IA接口,则作为连接点
应用:针对某个具体的代理提供的配置。比target 切点粒度细致。因为目标对象可以多实现。代理对象可以针对目标对象实现的多个接口的某一个接口,提供特定的切点。如:银行中的登录,银行中的帐户种类非常多。且有交叉。如:借记卡,贷记卡,借记还贷卡,贷记还贷卡等。可以针对还贷接口提供一个切点,做还贷信息的记录等。

within表达式

以包作为目标,定义切点。
语法:within(包名.*)
说明:在包中任意接口或类型都作为切点。
应用:针对某一个包提供的切点,粒度比target 粗糙。如:某包中的所有接口都需要执行某附属逻辑。如:电商平台中的下订单。下订单服务中可能需要特定的逻辑(时间戳校验,库存检查等),这些逻辑,是其他业务线中不需要提供切面的。

args表达式

以参数标准作为目标,定义切点。
语法:args(类型,类型)
说明:方法的参数表符合要求的时候,作为切点。参数表是有顺序的。
应用:主要应用在参数校验中。如:登录的时候必须传递两个字符串参数(登录名和密码)。可以使用args 来限定。配合这execution 实现。如:execution( * xxxx.*.login(..) ) args(string,string)。是使用频率最低的表达式。

SpringMVC组件实现逻辑

执行逻辑图

在这里插入图片描述

组件介绍

DispatcherServlet

DispatcherServlet是整个流程控制的中心,由它调用其他组件处理用户请求。DispatherServlet的存在降低了组件之前的耦合性。
MVC模式:传统定义中:一个WEB应用中,只有一个控制器和客户端交互。所有的客户端请求和服务端单点接触。这个控制器称为核心控制器(前端控制器)。传统定义中,核心控制器的实现使用Servlet。如SpringMVC、struts1。
MVC优势:单点接触,可以有效的解耦。可以实现功能的重用。
M-model:
V-view:
C-controller

HandlerMapping

处理映射器
HandlerMapping负责根据用户请求找到Handler,即处理器。SpringMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
映射器相当于配置信息或注解描述。映射器内部封装了一个类似map 的数据结构。使用URL 作为key,HandlerExecutionChain 作为value。
核心控制器,可以通过请求对象(请求对象中包含请求的URL)在handlerMapping 中查询HandlerExecutionChain 对象。
是SpringMVC 核心组件之一。是必不可少的组件。无论是否配置,SpringMVC 会有默认提供。
如果有<mvc:annotation-driven/> 标签配置,默认的映射器:RequestMappingHandlerMapping
如果没有<mvc:annotation-driven/>标签配置,且使用注解开发SpringMVC 代码,默认的映射器是:RequestMappingHandlerMapping。(老版本中有其他的映射器,但是已经过时。)

HandlerAdapter

通过HandlerAdapter对处理器(Handler)进行执行。这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
典型的适配器:SimpleControllerHandlerAdapter。最基础的。处理自定义控制器(Handler)和SpringMVC控制器顶级接口Controller之间关联的。
如果定义了<mvc:annotation-driven/> 标签配置,使用适配器对象为:HttpRequestHandlerAdapter。
适配器也是SpringMVC 中的核心组件之一。必须存在。SpringMVC 框架有默认值。

Handler

处理器。
Handler是继DispatcherServlet前端控制器的后端控制器(自定义控制器),在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。
在SpringMVC 中对Handler 没有强制的类型要求。在SpringMVC 框架中,对Handler的引用定义类型为Object。
处理器理论上说不是必要的核心组件。
SpringMVC 框架是一个线程不安全的,轻量级的框架。一个handler对象,处理所有的请求。开发过程中,注意线程安全问题。

ViewResovler

ViewResolver负责将处理结果(ModelAndView)生成View视图,ViewResolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View 视图对象,最		后对View 进行渲染将处理结果通过页面展示给用户。
是SpringMVC 中必要的组件之一。SpringMVC 提供默认视图解析器。InternalResourceViewResolver。内部资源视图解析器。
视图解析器是用于处理动态视图逻辑的。静态视图逻辑,不通过SpringMVC 流程。直接通过WEB 中间件(Tomcat)就可以访问静态资源。

SpringMVC执行流程

在这里插入图片描述

Mybatis-generator-console

插件工具。是用于自动生成代码的。可以生成的代码,包括:实体类型、Mapper接口以及Mapper接口对应的SQL映射文件。

版权声明:本文为weixin_39009248原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。