spring原理

spring 之7种重要设计模式

ぃ、小莉子 提交于 2020-03-09 08:52:44
Spring中涉及的设计模式总结 1.简单工厂(非23种设计模式中的一种) 实现方式: BeanFactory。Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。 实质: 由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 实现原理: bean容器的启动阶段: 读取bean的xml配置文件,将bean元素分别转换成一个BeanDefinition对象。 然后通过BeanDefinitionRegistry将这些bean注册到beanFactory中,保存在它的一个ConcurrentHashMap中。 将BeanDefinition注册到了beanFactory之后,在这里Spring为我们提供了一个扩展的切口,允许我们通过实现接口BeanFactoryPostProcessor 在此处来插入我们定义的代码。典型的例子就是:PropertyPlaceholderConfigurer,我们一般在配置数据库的dataSource时使用到的占位符的值,就是它注入进去的。 容器中bean的实例化阶段: 实例化阶段主要是通过反射或者CGLIB对bean进行实例化,在这个阶段Spring又给我们暴露了很多的扩展点: 各种的Aware接口 ,比如

Spring中IOC3个最主要的类

佐手、 提交于 2020-03-08 01:14:25
IOC(控制反转)、DI(依赖注入)是Spring的特性中耳熟能详的两种 平时我们获取Bean都是采取自动注入,或者使用getBean()方法,器根本原理,如下图: 平时我们知道的类也就是ApplicationContext,因为他是Spring的主入口。当IOC容器初始化时,会读取配置文件application.xml,然后根据扫描的类,生成Bean缓存起来,存到内存里面(不重复读取,不重复加载配置文件) 首先,BeanDefinitionReader,他是一个方法类,它的作用就是讲配置文件进行读取,并且将类的配置信息读取到BeanDefinition中 Bean常用的类型: prototype(每次用一个new一个) singleton(生成一次一直在) proxy(代理对象,新的字节码文件去实现原来的类) 其他类型等等 BeanDefinition类的作用,就是保存我们读取到的配置信息,保存生成的Bean的一些配置信息 当我们创建一个对象时,他会先去BeanDfinition中,根据对象的标识获取对象的基本配置信息,然后才能够创建出对象。 那BeanWrapper类的作用呢?请先看以下伪代码 Class A { private B b ; } Class B { private A a ; } 这是对象的一种依赖方式,循环依赖,当我们注入A对象时,发现需要B对象

Spring扩展点之Aware接口族

久未见 提交于 2020-03-07 13:39:01
引言 Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContextAware,EnvironmentAware,BeanClassLoaderAware等,这些Aware的作用都可以从命名得知 Aware 处理 其中 BeanNameAware 、 BeanClassLoaderAware 和 BeanFactoryAware 这三个是直接在bean的初始化之前就处理了的,具体代码在 AbstractAutowireCapableBeanFactory.initializeBean 方法中: protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { // 判断对象实现的接口类型,处理特定的三种接口类型:BeanNameAware、BeanClassLoaderAware和BeanFactoryAware。 if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof

spring生命周期

落爺英雄遲暮 提交于 2020-03-05 20:59:27
Github地址 最近在整合mybatis-spring。 公司里面已经有一个叫做kylin-datasource的开发包,以前能够提供master和slave2个数据源,最近更新了2.0版本,支持自动扫描mapper了(之前每写一个mapper都要自己去配个factory)。 在毕业设计的项目里面,我也准备自己写一个mybatis与spring整合的依赖,并且希望在这个包原有的基础上,写的尽量完善一些。 同时也是为了能够更加深的去了解spring的原理。 自己建项目,将源代码类一个个拷过来,运行的时候,还是报错了:原先有3个datasouce,datasource\masterDatasource\slaveDatasource,所以在注入的时候找到了3个,spring不知道该怎么办了。 只好将所有slave相关的先删了,保证能够访问数据库先再说。 中间虽然也遇到了非常多的问题,但最终还是让一个master的依赖可用了。同时,我也对原先的代码一顿改,改成我看的习惯的样子。。 加载配置文件 这是今天遇到的主要问题: 使用@EnableConfigurationProperties 让properties中的属性自动注入到bean的属性中,这个bean叫做DatasourceProperties。 这种方法看上去非常优雅,,我也不想舍弃。

Spring事务管理-@Transactional注解详解

瘦欲@ 提交于 2020-03-05 15:02:37
一、概念 首先事务 是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务有 Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)四种特性,简称ACID四特性。 原子性 事务最基本的操作单元,要么全部成功,要么全部失败,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。 一致性 事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。 隔离性 指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。 持久性 指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。 二、Transactional注解原理 spring 在扫描bean的时候会扫描方法上是否包含

Spring事务失效

倖福魔咒の 提交于 2020-03-02 18:05:31
面试必备技能:JDK动态代理给Spring事务埋下的坑 一、场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1、场景A: 这里其实是分别执行了两个事物,执行的结果是两个方法都可以插入数据!如下: 2、场景B: 修改上述代码如下: Propagation.REQUIRES_NEW的含义表示:如果当前存在事务,则挂起当前事务并且开启一个新事物继续执行,新事物执行完毕之后,然后在缓刑之前挂起的事务,如果当前不存在事务的话,则开启一个新事物。 执行的结果是两个方法都可以插入数据!执行结果如下: 场景A和场景B都是正常的执行,期间没有发生任何的回滚,假如child()方法中出现了异常! 3、场景C 修改child()的代码如下所示,其他代码和场景B一样: 执行结果如下,会出现异常,并且数据都没有插入进去: 疑问1:场景C中child()抛出了异常,但是parent()没有抛出异常,按道理是不是应该parent()提交成功而child()回滚? 可能有的小伙伴要说了,child()抛出了异常在parent()没有进行捕获,造成了parent()也是抛出了异常了的!所以他们两个都会回滚! 4、场景D 按照上述小伙伴的疑问这个时候,如果对parent()方法修改

DelegatingFilterProxy的原理及运用

这一生的挚爱 提交于 2020-03-02 16:39:02
DelegatingFilterProxy的原理及使用 DelegatingFilterProxy就是一个对于servlet filter的代理,用这个类的好处主要是通过Spring容器来管理servlet filter的生命周期,还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。 DelegatingFilterProxy的使用方法, 首先在web.xml中配置: <filter> < filter-name>myFilter</filter-name> < filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> < filter-name>myFilter</filter-name> < url-pattern>/*</url-pattern> </filter-mapping> 然后在Spring的配置文件中,配置具体的Filter类的实例。 <bean name="myFilter" class="com.*.MyFilter"></bean> 在Spring中配置的bean的name要和web.xml中的

Spring整合Mybatis原理简单分析

荒凉一梦 提交于 2020-03-01 09:55:51
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 配置数据库表对应的java实体类 --> <property name="typeAliasesPackage" value="com.test.pojo" /> <!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --> <property name="mapperLocations" value="classpath:com/test/mapping/*.xml" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.test.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> 上面是一般项目中的配置,根据该配置分析 1,获取SqlSessionFactory

Spring Proxy 动态代理(ProxyFactory)

二次信任 提交于 2020-02-28 23:47:32
一、动态代理生成技术栈分为两种: 1、JDK动态代理 JDK动态代理只能对实现了接口的类生成代理,而不能针对类 2、Cglib动态代理 CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承) 二、Spring在选择用JDK还是CGLiB的依据: (1)当Bean实现接口时,Spring就会用JDK的动态代理 (2)当Bean没有实现接口时,Spring使用CGlib是实现 (3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>) 三、CGlib比JDK快?   (1)使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。   (2)在对JDK动态代理与CGlib动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGlib要好20%左右。 四、Spring 动态代理如何封装的; 来源: https://www.cnblogs.com/wangwei1986/p/9377504.html

Spring的事件机制详解

蹲街弑〆低调 提交于 2020-02-26 05:12:21
同步事件和异步事件   同步事件:在一个线程里,按顺序执行业务,做完一件事再去做下一件事. 异步事件:在一个线程里,做一个事的同事,可以另起一个新的线程执行另一件事,这样两件事可以同时执行.   用一个例子来解释同步事件和异步事件的使用场景,有时候一段完整的代码逻辑,可能分为几部分,拿最常见的注册来说,假设完整流程是,1.点击注册->2.检验信息并存库->3.发送邮件通知->4.返回给用户.代码这么写是正确,但不是最好的,缺点如下:  1.逻辑复杂,业务耦合,我们把校验数据并存库和发送邮件写到一个大的业务方法里了,发邮件我们可以看做一个相对独立的业务方法     2.效率低,假设2和3分别需要1秒的时候,那么用户在点击注册2秒后才能看到相应   同步事件可以解决上面第一个问题,我们把发邮件的方法独立出来,放到事件里执行,这样注册的这个方法就可以只做2操作,完成之后发布一个事件去执行3,可以很好的解决业务耦合的问题.   异步事件可以完美解决以上两个问题,注册方法执行2操作,执行之后发布一个异步事件,另起一个线程执行3操作,注册方法所在的线程可直接返回给用户,这样不仅实现了业务解耦还提高了效率,用户点击注册,1秒后就能看到响应. Spring的事件机制   spring事件发送监听涉及3个部分   ApplicationEvent:表示事件本身,自定义事件需要继承该类