Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只须要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。java
主要由如下几个模块组成:web
Spring Core:核心容器,提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC)模式,将应用程序的配置和依赖性规范与实际的应用程序代码分开。正则表达式
Beans模块:提供了BeanFactory,是工厂模式的经典实现,Spring将管理对象称为Bean。spring
Core核心模块:提供了Spring框架的基本组成部分,包括Ioc和Di.数据库
Context:Spring上下文,是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。编程
Expression Language 模块:是运行时查询和操做对象图的强大的表达式语言。缓存
Spring AOP:经过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。能够很容易地使 Spring框架管理的任何对象支持AOP。Spring AOP模块为基于 Spring 的应用程序中的对象提供了事务管理服务。经过使用 Spring AOP,就能够将声明性事务管理集成到应用程序中。安全
Spring DAO:DBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不一样数据库供应商抛出的错误消息。异常层次结构简化了错误处理,而且极大地下降了须要编写的异常代码数量(例如打开和关闭链接)。Spring DAO 的面向 JDBC 的异常听从通用的 DAO 异常层次结构。session
Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括JDO、Hibernate和iBatis SQL Map。全部这些都听从 Spring 的通用事务和 DAO 异常层次结构。app
Spring Web:Web上下文模块创建在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。因此Spring 框架支持与 Jakarta Struts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工做。
Spring MVC:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。经过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
(1)spring属于低侵入式设计,代码的污染极低;
(2)spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;
(3)Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。
(4)spring对于主流的应用框架提供了集成支持。
三、Spring框架核心组件
(1)BeanFactory
(2)ApplicationContext
(3)IOC控制反转
(4)DI依赖注入
(5)AOP面向切面编程
所谓IoC,对于spring框架来讲,就是由spring来负责控制对象的生命周期和对象间的关系。
IoC的一个重点是在系统运行中,动态的向某个对象提供它所须要的其余对象。这一点是经过DI(Dependency Injection,依赖注入)来实现的.
DI注入的方式: setter 注入、构造器注入、注解注入。
1.IOC容器的概念:IoC容器就是具备依赖注入功能的容器,IoC容器负责实例化、定位、配置应用程序中的对象及创建这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IoC容器进行组装。在Spring中BeanFactory是IoC容器的实际表明者。
2.Bean的概念:由IoC容器管理的那些组成应用程序的对象咱们就叫它Bean, Bean就是由Spring容器初始化、装配及管理的对象,除此以外,bean就与应用程序中的其余对象没有什么区别了。
什么是做用域呢?即“scope”,在面向对象程序设计中通常指对象或变量之间的可见范围。而在Spring容器中是指其建立的Bean对象相对于其余Bean对象的请求可见范围。
基本的做用域:
1.singleton:指“singleton”做用域的Bean只会在每一个Spring IoC容器中存在一个实例,并且其完整生命周期彻底由Spring容器管理。对于全部获取该Bean的操做Spring容器将只返回同一个Bean。
2.prototype:即原型,指每次向Spring容器请求获取Bean都返回一个全新的Bean,相对于“singleton”来讲就是不缓存Bean,每次都是一个根据Bean定义建立的全新Bean。
3.request:表示每一个请求须要容器建立一个全新Bean。好比提交表单的数据必须是对每次请求新建一个Bean来保持这些表单数据,请求结束释放这些数据。
4.session:表示每一个会话须要容器建立一个全新Bean。好比对于每一个用户通常会有一个会话,该用户的用户信息须要存储到会话中,此时能够将该Bean配置为web做用域。
5.globalSession:相似于session做用域,只是其用于portlet环境的web应用。若是在非portlet环境将视为session做用域。
1. 实例化一个Bean,也就是咱们一般说的new;
2. 按照Spring上下文对实例化的Bean进行配置,也就是DI依赖注入;
3. 若是这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID;
4. 若是这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂自己(能够用这个方法获取到其余Bean);
5. 若是这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式一样能够实现步骤4,但比4更好,觉得ApplicationContext是BeanFactory的子接口,有更多的实现方法;
6. 若是这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean内容的更改,而且因为这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术;
7. 若是这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法;
8. 若是这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法;
注意:以上工做完成之后就能够用这个Bean了,那这个Bean是一个single的,因此通常状况下咱们调用同一个ID的Bean会是在内容地址相同的实例;
9. 当Bean再也不须要时,会通过清理阶段,若是Bean实现了DisposableBean接口,会调用其实现的destroy方法;
10. 最后,若是这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法;
1、 @Value赋值和@propertySource加载外部配置文件
1.@Value 通常用在属性和setter方法上,当该类注册成bean时,会自动为其属性或方法的参数赋值。注意:必定不能用在静态方法上,不然会失效
2.用法:
@Value("placeholder") //赋予指定值
@Value("${placeholder}") //赋予配置文件中指定key为placeholder的值
3.@PropertySource("classpath:application.properties") //导入指定的配置文件,通常写在主配置类上
二 、@Autowired和@Qualifier和@Primary
一、@Autowired(required=boolean) // 默认byType注入,若是找到多个相同类型的组件,再将属性的名称byName去注入,required设置是否必须注入,默认true,可用于属性、方法、构造器、参数
二、@Qualifier("name") //与@Autowired搭配使用让@Autowired变成byName去注入
三、@Primary //当多个bean是同一个类型时,@Autowired会首选@Primary 的bean去装配
@Autowired和@Resource之间的区别:
(1) @Autowired默认是按照类型装配注入的,默认状况下它要求依赖对象必须存在(能够设置它required属性为false)。
(2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。
三 、@Resource和@Inject
一、@Resource(name="name") //能够和@Autowired同样实现自动注入功能,默认byName进行装配;但不能支持 @Primary 和 @Autowired(required=false)
二、@Inject //须要导入javax.inject包才有这个注解,和@Autowired功能同样,可是没有 @Autowired(required=false) 功能
4、自动装配
在spring中,对象无需本身查找或建立与其关联的其余对象,由容器负责把须要相互协做的对象引用赋予各个对象,使用autowire来配置自动装载模式。
在Spring框架xml配置中共有5种自动装配:
(1)no:默认的方式是不进行自动装配的,经过手工设置ref属性来进行装配bean。
(2)byName:经过bean的名称进行自动装配,若是一个bean的 property 与另外一bean 的name 相同,就进行自动装配。
(3)byType:经过参数的数据类型进行自动装配。
(4)constructor:利用构造函数进行装配,而且构造函数的参数经过byType进行装配。
(5)autodetect:自动探测,若是有构造方法,经过 construct的方式自动装配,不然使用 byType的方式自动装配。(1)Spring事务的种类:
spring支持编程式事务管理和声明式事务管理两种方式:
①编程式事务管理使用TransactionTemplate。
②声明式事务管理创建在AOP之上的。其本质是经过AOP功能,对方法先后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始以前加入一个事务,在执行完目标方法以后根据执行状况提交或者回滚事务。
声明式事务最大的优势就是不须要在业务逻辑代码中掺琐事务管理的代码,只需在配置文件中作相关的事务规则声明或经过@Transactional注解的方式,即可以将事务规则应用到业务逻辑中。
@Transactional(timeout = 30, readOnly = false, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
1. timeout 事务的超时时间,默认值为-1,表示没有超时显示。若是配置了具体时间,则超过该时间限制但事务尚未完成,则自动回滚事务。
2.read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不须要事务的方法,好比读取数据,能够设置 read-only 为 true。
3. rollback-for 用于指定可以触发事务回滚的异常类型,若是有多个异常类型须要指定,各种型之间能够经过逗号分隔。
4.no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。
5.isolation 事务的隔离度,默认值采用 DEFAULT。
声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就能够得到彻底的事务支持。惟一不足地方是,最细粒度只能做用到方法级别,没法作到像编程式事务那样能够做用到代码块级别。
(2)spring的事务传播行为:
事务传播(Propagation)特性是指不一样业务(service)对象中的事务方法之间相互调用时,事务的传播方式。
① PROPAGATION_REQUIRED:若是当前没有事务,就建立一个新事务,若是当前存在事务,就加入该事务,该设置是最经常使用的设置。(默认)
② PROPAGATION_SUPPORTS:支持当前事务,若是当前存在事务,就加入该事务,若是当前不存在事务,就以非事务执行。‘
③ PROPAGATION_MANDATORY:支持当前事务,若是当前存在事务,就加入该事务,若是当前不存在事务,就抛出异常。
④ PROPAGATION_REQUIRES_NEW:建立新事务,不管当前存不存在事务,都建立新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。
⑥ PROPAGATION_NEVER:以非事务方式执行,若是当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则按REQUIRED属性执行。
(3)Spring中的隔离级别:
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED:读未提交,容许另一个事务能够看到这个事务未提交的数据。
③ ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才能被另外一事务读取,并且能看到该事务对已有记录的更新。
④ ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才能被另外一事务读取,可是不能看到该事务对已有记录的更新。
⑤ ISOLATION_SERIALIZABLE:一个事务在执行的过程当中彻底看不到其余事务对数据库所作的更新。
AOP,通常称为面向切面,做为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减小系统中的重复代码,下降了模块间的耦合度,同时提升了系统的可维护性。可用于权限认证、日志、事务处理。
AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的表明为AspectJ;动态代理则以Spring AOP为表明。
(1)AspectJ是静态代理的加强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,所以也称为编译时加强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是加强以后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的所有方法,而且在特定的切点作了加强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:
①JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 经过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一块儿;接着,Proxy利用 InvocationHandler动态建立一个符合某一接口的的实例, 生成目标类的代理对象。
②若是代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,能够在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加加强代码,从而实现AOP。CGLIB是经过继承的方式作的动态代理,所以若是某个类被标记为final,那么它是没法使用CGLIB作动态代理的。
(3)静态代理与动态代理区别在于生成AOP代理对象的时机不一样,相对来讲AspectJ的静态代理方式具备更好的性能,可是AspectJ须要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。
在AOP中,经过切入点选择目标对象的链接点,而后在目标对象的相应链接点处织入通知,而切入点和通知就是切面(横切关注点),而在目标对象链接点处应用切面的实现方式是经过AOP代理对象;
切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个链接点,Spring AOP支持的AspectJ切入点指示符以下:
execution:用于匹配方法执行的链接点;
within:用于匹配指定类型内的方法执行;
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
@within:用于匹配因此持有指定注解类型内的方法;
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
@annotation:用于匹配当前执行方法持有指定注解的方法;
bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
reference pointcut:表示引用其余命名切入点,只有@ApectJ风格支持,Schema风格不支持。