一、轻量级、非侵入式的框架;对现有的类结构没有影响
二、能够提供众多服务,如事务管理、WS(WebService)等
三、AOP很好支持、方便面向切面编程、将业务逻辑和系统服务分开
四、对主流的框架提供了很好的集成支持,如hibernate、Struts二、JPA等,像一个胶水同样,把一些好的框架粘合在一块儿方便使用
五、使用Spring的IOC容器,将对象之间的依赖关系交给Spring,下降组件之间的耦合性,让咱们更专一于应用逻辑代码
六、Spring DI机制下降了业务对象替换的复杂性。
七、Spring的高度可开放性,并不强制依赖于Spring,开发者能够自由选择Spring部分或所有
复制代码
一、缺乏一个公用控制器
二、没有SpringBoot好用
三、Spring像一个胶水,将框架黏在一块儿,后面拆分的话就不容易拆分了
复制代码
依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色须要另一个角色协助的时候,在传统的程序设计过程当中,一般由调用者来建立被调用者的实例。但在spring中建立被调用者的工做再也不由调用者来完成,所以称为控制反转。建立被调用者的工做由spring来完成,而后注入调用者所以也称为依赖注入
复制代码
一、核心业务功能和切面功能分别独立进行开发 ,而后把切面功能和核心业务功能 "编织" 在一块儿,这就叫AOP
二、让关注点代码与业务代码分离(各个步骤之间良好的隔离性、源代码无关性)
三、面向切面编程就是指: 对不少功能都有的重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。
四、应用场景:日志,事务管理,权限控制
复制代码
主要经过Proxy.newProxyInstance()和InvocationHandler这两个类和方法实现spring
cglib数据库
生成对象类型为Enhancer编程
实现原理相似于 jdk 动态代理,只是他在运行期间生成的代理对象是针对目标类扩展的子类缓存
静态代理markdown
在编译的时候就直接生成代理类session
缺点:若是要代理一个接口的多个实现的话须要定义不一样的代理类 代理类 和 被代理类 必须实现一样的接口,万一接口有变更,代理、被代理类都得修改数据结构
jdk和cglib的对比框架
XML方式maven
注解方式学习
基于JAVA类配置
经过 @Configuration 和 @Bean 这两个注解实现的
@Configuration 做用于类上,至关于一个xml配置文件;
@Bean 做用于方法上,至关于xml配置中的bean;
装配方式(依赖注入的具体行为)
i、基于注解的自动装配
注解:
@Autowired(byType)+@Qualifier
@Resource(byName)
自动扫描:
component-scan
ii、基于XML配置的显式装配
iii、基于Java配置的显式装配
能在编译时就发现错误
依赖注入的方式
i、构造器方式注入
构造器依赖注入经过容器触发一个类的构造器来实现的,该类有一系列参数,每一个参数表明一个对其余类的依赖。
例如:<bean id="hello" class="com.maven.Hello"><property name="text" ref="text" /></bean>
复制代码
ii、settter方法注入
之因此叫setter方法注入,由于这是经过找到类的对应的setter方法,再进行相应的注入
Setter方法注入是容器经过调用无参构造器或无参static工厂 方法实例化bean以后,调用该bean的setter方法,即实现了基于setter的依赖注入。
iii、最好的解决方案是
用构造器参数实现强制依赖,setter方法实现可选依赖
循环依赖 i、构造器方式没法解决,只能抛出异常
ii、多例方式没法解决,只能抛出异常
由于Spring容器不缓存"prototype"做用域的bean,所以没法提早暴露一个建立中的bean。
iii、单例模式能够解决
经过提早暴露一个单例工厂方法,从而使其余bean可以引用到该bean提早暴露一个正在建立中的bean
iiii、不用建立对象,而只须要描述它如何被建立,不在代码里直接组装组件和服务,可是要在配置文件里描述哪些组件须要哪些服务,以后一个容器(IOC容器)负责把他们组装起来。
1.Resource定位;指对BeanDefinition的资源定位过程。通俗地讲,就是找到定义Javabean信息的XML文件,并将其封装成Resource对象。
2.BeanDefinition的载入;把用户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数据结构就是BeanDefinition。
3.向IoC容器注册这些 BeanDefinition。
2. bean的做用域
1). singleton
singleton是Bean的默认做用域
默认状况下是容器初始化的时候建立,但也可设定运行时再初始化bean
DefaultSingletonBeanRegistry类里的singletonObjects哈希表保存了单例对象。
Spring IoC容器中只会存在一个共享的Bean实例,不管有多少个Bean引用它,始终指向同一对象。
Spring容器能够管理singleton做用域下bean的生命周期,在此做用域下,Spring可以精确地知道bean什么时候被建立,什么时候初始化完成,以及什么时候被销毁
复制代码
2). prototype
每次经过Spring容器获取prototype定义的bean时,容器都将建立一个新的Bean实例,每一个Bean实例都有本身的属性和状态
当容器建立了bean的实例后,bean的实例就交给了客户端的代码管理,Spring容器将再也不跟踪其生命周期,而且不会管理那些被配置成prototype做用域的bean的生命周期。
对有状态的bean使用prototype做用域,而对无状态的bean使用singleton做用域。
复制代码
3). request
在一次Http请求中,容器会返回该Bean的同一实例。而对不一样的Http请求则会产生新的Bean,并且该bean仅在当前Http Request内有效。
复制代码
4). session
在一次Http Session中,容器会返回该Bean的同一实例。而对不一样的Session请求则会建立新的实例,该bean实例仅在当前Session内有效。
复制代码
5). global Session
在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。
复制代码
bean的建立
1.进入getBean()方法
2.判断当前bean的做用域是不是单例,若是是,则去对应缓存中查找,没有查找到的话则新建实例并保存。若是不是单例,则直接新建实例(createBeanInstance)
3.新建实例后再将注入属性(populateBean),并处理回调
1).建立bean
2).找到@Autowired的对象
3).建立注入对象,并赋值
复制代码
若是须要某一组操做具备原子性,就用注解的方式开启事务,按照给定的事务规则来执行提交或者回滚操做
事务管理通常在Service层
编程式事务控制(用户经过代码的形式手动控制事务)
1).Conn.setAutoCommite(false); // 设置手动控制事务
2).粒度较细,比较灵活,但开发起来比较繁琐: 每次都要开启、提交、回滚
复制代码
声明式事务控制(Spring提供对事物的控制管理)
1).XML方式
2).注解方式
复制代码
事务传播行为
required_new:若是当前方法有事务了,当前方法事务会挂起,在为加入的方法开启一个新的事务,直到新的事务执行完、当前方法的事务才开始
required(默认方法):若是当前方法已经有事务了,加入当前方法事务
其他五种方式(拓展学习)
事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另外一个方法的时候事务如何传播。
数据库的隔离级别(参考隔离级别的那篇文章)
事务超时属性
指一个事务所容许执行的最长时间,若是超过该时间限制但事务尚未完成,则自动回滚事务。
事务只读属性
对事物资源是否执行只读操做
回滚规则
定义了哪些异常会致使事务回滚而哪些不会。默认状况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚,也能够用用户本身定义
PlatformTransactionManager
TransactionDefinition
TransactionStatus
若是在dao层,回滚的时候只能回滚到当前方法,但通常咱们的service层的方法都是由不少dao层的方法组成的
若是在dao层,commit的次数会过多
1.加载和实例化
2.初始化
3.请求处理
4.服务终止