Spring、SpringMVC原理简述

一、Spring IOC

IOC控制反转,是一种思想,意味着将你设计好的对象交给容器控制而非自己直接控制,使用时由容器创建及注入依赖对象。

DI依赖注入,组件间的依赖关系由容器在运行时决定;依赖注入的目的并非为软件系统带来更多功能,而是提升组件重用的频率。

https://www.cnblogs.com/xdp-gacl/p/4249939.html

二、Spring Bean加载流程

Spring Bean初始化过程:首先读取XML中的bean(id、class、scope、depends on、lazyInit、init-method、destroy-method)初始化为BeanDefinition;通过BeanDefinition将bean注册至DefaultListableBeanFactory保存在一个ConcurrentHashMap;将bean注册后Spring提供扩展的切口允许通过实现BeanFactoryPostProcessor插入自定义代码(例如PropertyPlaceholderConfigurer处理配置中${}占位符为实际值);

Bean的实例化阶段通过反射或者Cglib对Bean进行实例化,暴露很多扩展点;实现BeanFactoryAware、MessageSourceAware、ApplicationContextAware等Aware接口,实例化bean时Spring会注入对应的BeanFactory、MessageSource、ApplicationContext实例;实现BeanFactoryProcessor接口的bean,实例化bean时Spring调用接口的方法,postProcessBeforeInitialization方法在InitializingBean接口的 afterPropertiesSet方法之前执行,而postProcessAfterInitialization方法在 InitializingBean接口的afterPropertiesSet方法之后执行;InitializingBean接口和 DisposableBean接口对应于<bean/>的init-method和destory-method属性;

实现FactoryBean接口的bean其特点是spring使用getBean()获取bean时会自动调用该Bean的getObject()方法,返回不是factory这个bean而是bean.getObject()方法的返回值,如spring集成mybatis时返回SqlSessionFactory而不是org.mybatis.spring.SqlSessionFactoryBean(SqlSessionFactoryBean是生产SqlSessionFactory的工厂,而SqlSessionFactory又是生产SqlSession的工厂)。

依赖注入的方式分为构造函数<constructor-arg>注入和setter方法<property>注入。

Spring Bean的生命周期

影响多个Bean的接口(实现接口的Bean会切入到多个Bean的生命周期):InstantiationAwareBeanPostProcessor(实例化阶段前后,postProcessBeforeInstantiation方法在自定义了TargetSource时替换代理类、postProcessAfterInstantiation方法在属性赋值方法内,但在真正执行赋值操作之前,返回值为boolean,false时可阻断属性赋值阶段,非自定义TargetSource时替换代理类,Spring AOP实现)BeanPostProcessor(初始化阶段前后,也是postProcessBeforeInstantiation、postProcessAfterInstantiation方法)、

影响单个Bean的接口(Aware类接口,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware(初始化阶段之前调用)EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware(postProcessBeforeInstantiation方法调用)

两个生命周期接口:InitializingBean(初始化阶段,除实现InitializingBean接口外还可通过注解或者xml配置的方式指定初始化方法)、DisposableBean(销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现DisposableBean接口Bean然后调用destroy方法)

BeanPostProcessor也会注册为Bean,Spring首先调用registerBeanPostProcessors()进行BeanPostProcessors的注册,然后执行finishBeanFactoryInitialization初始化单例非懒加载的Bean。BeanPostProcessor可以存在多个,每个BeanPostProcessor均影响多个Bean,不同实例执行顺序通过继承排序接口PriorityOrdered、Ordered实现,实现PriorityOrdered接口首先被执行,同继承PriorityOrdered接口的实例之间通过接口返回值排序,而实现Ordered接口其次被执行,未实现接口最后执行

三、Spring AOP

Spring AOP面向切面编程,面向对象编程的补充(面向对象编程的关键单元是对象,面向切面编程的关键单元是切面),简而言之就是在方法执行前后添加一段代码。使用场景一般为:事务、权限、日志、安全等。

concern和cross-cutting concern:关注点即在应用模块中实现的行为;横切关注点即贯穿整个应用程序的关注点(日志、安全、数据转换);

AOP的实现:Aspect、Spring AOP(Aspect注解风格和Spring XML配置风格)、Jboss AOP

Spring通知类型:Before前置通知、After后置通知、AfterReturning正常返回通知、AfterThrowing抛出异常通知、Around环绕通知

Spring AOP代理:默认使用JDK动态代理(针对接口),针对非接口使用Cglibc代理。

引介(Introduction):可以让一个切面声明被通知的对象实现没有实现的额外接口(@DeclareParaents)

连接点Joint Point和切入点Point Cut:连接点是程序执行的一个点,代表一个方法执行。切入点是匹配连接点的一个断言或者表达式。

Weaving织入:Spring AOP仅支持Aspectj几个类型的切入点类型,允许将AOP运用到IOC的声明的Bean中。若想使用额外的切入点类型,则直接使用Aspectj框架使用它的织入特性。

Aspectj编译时织入:通过ajc特殊的Aspectj编译器完成,编译时将切面织入到java源码文件,输入织入的class文件。

Aspectj编译后织入:通过ajc特殊的Aspectj编译器可以将切面织入到编译后的class文件或jar中

Aspectj加载时织入(LTW):在目标类被类加载器加载至JVM时触发,被注入对象需要一个特殊的类加载器来增强目标类的字节码。

https://blog.csdn.net/dadiyang/article/details/82920139

四、Spring MVC流程

1、客户端(浏览器)发动请求,直接到DispatcherServlet

2、DispatcherServlet根据请求信息调用HandlerMapping,解析相应的Handler

3、解析到的Handler由HandlerAdapter处理,请求并处理业务逻辑

4、Handler处理后返回ModelAndView对象(Model表示数据对象,View表示逻辑View)

5:ViewResolver根据逻辑View解析实际View(JSP等)

6:DispatcherServlet将返回的Model传给View(视图渲染)

7:最后将View返回给请求者(浏览器)

Spring MVC创建拦截器:实现HandlerInterceptor/继承HandlerInterceptorAdapter

通过mvc xml配置、继承WebMvcConfigurerAdapter、WebMvcConfigurationSupport重写拦截器addInterceptors方法、反射方式获取bean处理interceptors属性字段。

五、Mybatis

Mybatis是一个半ORM(对象关系映射,但需手动编写SQL)框架,内部封装JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需关注如何编写SQL语句,即可严格控制sql执行性能,灵活度高。

Mapper接口的工作原理是JDK动态代理,Mybatis运行时使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,根据接口名称、方法名,唯一定位一个MapperStatement,之后调用执行器执行配置SQL,最后将SQL执行结果返回。

Mybatis集成Spring初始化时将包路径下的所有Mapper接口注册到Spring Bean中,并将beanClass设置为MapperFactoryBean。MapperFactoryBean实现FactoryBean接口。当通过 @Autowired 注入Dao接口的时候,返回对象即MapperFactoryBean的getObject()方法对象。该方法通过JDK动态代理,返回了一个Mapper接口的代理对象(代理对象处理器是MapperProxy对象),当调用接口的方法,则调用到MapperProxy对象的invoke()方法。

5.1 缓存机制

       一级缓存: 基于PerpetualCache的HashMap本地缓存,存储作用域为Session,当Session flush或close后,该Session中所有Cache将清空,默认打开一级缓存。

       二级缓存:默认采用 PerpetualCache的HashMap存储,存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认未打开,若需开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),配置标签        <cache/> ;

       缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)进行了C/U/D 操作后,默认该作用域下所有 select 中缓存将被 clear 掉并重新更新,若开启了二级缓存,则只根据配置判断是否刷新。

        Spring集成mybatis后原DefaultSqlSession被替换为SqlSessionFatory调用时每次获取新的SqlSession,由于一级缓存基于Session因此一般情况下一级缓存失效,而当使用事务使用ThreadLocal保证事务中获取到的SqlSession相同,一级缓存才生效

5.2 延迟加载

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载(配置是否启用延迟加载:lazyLoadingEnabled=true|false)。

延迟加载的基本原理:使用cglib创建目标对象的代理对象,当get目标对象的某个属性时,拦截器invoke()方法发现该属性是NULL值,则调用关联对象或集合对象的SQL,查询结果后set属性值,接着get属性值时正常返回。

5.3 接口绑定

mybatis接口绑定2种实现方式:

1、基于XML配置

2、基于@Select、@Insert、@Update、@Delete注解配置

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值