1 spring概述
它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。
Spring是一个轻量级Java开发框架
Spring设计目标:Spring为开发者提供一个一站式轻量级应用开发平台;
但是 Spring 仍然可以和其他的框架无缝整合。
Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发
。
Spring所有的功能 的底层都依赖于
它的两个核心特性,也就是依赖注入
(dependency injection,DI
)和面向切面编
程(aspect-oriented programming, AOP
)
2 Spring的设计理念和核心
Spring设计理念:在JavaEE开发中,支持POJO和JavaBean开发方式,使应用 面向接口开发,充分支持OO(面向对象)设计方法;Spring通过IoC容器实现 对象耦合关系的管理,并实现依赖反转,将对象之间的依赖关系交给IoC容器, 实现解耦
Spring框架的核心:IoC容器和AOP模块
。
- 通过IoC容器管理 POJO对象以及他 们之间的耦合关系;
- 通过AOP以动态非侵入的方式增强服务。
IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的 功能分离出来形成可重用的功能组件
。
3 Spring的模块
Spring 总共大约有 20 个模块, 由 1300 多个不同的文件构成。 而这些组件被 分别整合在核心容器
(Core Container) 、 AOP
(Aspect Oriented Programming) 和设备支持
(Instrmentation)
、数据访问与集成
(Data Access/Integeration) 、 Web
、消息
(Messaging) 、 Test
等 6 个模块中
spring core
:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能
。
spring beans
:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean
。
spring context
:构建于 core 封装包基础上的 context 封装包,提供了一种框 架式的对象访问方法。
spring jdbc
:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂 商特有的错误代码解析, 用于简化JDBC
。
spring aop
:提供了面向切面的编程实现,让你可以自定义拦截器、切点等
。
spring Web
:提供了针对 Web 开发的集成特性
,例如文件上传,利用 servlet listeners 进行 ioc容器初始化和针对 Web 的 ApplicationContext。
spring test
:主要为测试提供支持
的,支持使用JUnit或TestNG对Spring组件进 行单元测试和集成测试。
4 Spring 框架中都用到了哪些设计模式
工厂模式
:BeanFactory就是简单工厂模式的体现,用来创建对象的实 例;单例模式
:Bean默认为单例模式。代理模式
:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生 成技术;模板方法
:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。观察者模式
:定义对象键一种一对多的依赖关系,当一个对象的状态发 生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中 listener的实现–ApplicationListener
5 核心容器(spring context应用上下文) 模 块
基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何以 spring为基础的应用的核心。Spring 框架建立在此模块之上,它使Spring成为 一个容器
。
Bean
工厂是工厂模式的一个实现,提供了控制反转功能
,用来把应用的配置和 依赖从真正的应用代码中分离。最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根据XML文件中的定义加载beans。
该容器从XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用
。
6 Spring 特点
轻量级
控制反转
面向切面
容器
框架集合
7 Spring 常用注解
bean 注入与装配的的方式有很多种, 简单易用的方式就是使用 Spring 的注解了,Spring 提供了大量的注解方式
注解 | 说明 |
---|---|
@Controller | 1. 用于标注控制层组件;;2. @Controller用于标记左一个类上,使用它标记的类就是一个SpringtMvC Controler对象 ;; 3. 分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解 ;; 4.可以把Request请求header部分的值线定到方法的参数上 |
@RestController | 相当与@Controller和@responseBody的组合效果 |
@Component | 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注, |
@Repository | 用于注解dao层,在daolmpl类上面注解。 |
@Service: | 用于标注业务层组件 |
注解 | 说明 |
---|---|
@ResponseBody | 1. 异步请求;; 2. 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。;; 3. 返回的数据不是htm标签的页面,而是其他某种格式的数据时(如json,xml等)便用 |
@RequestMapping | 一个用来处理请求地址映射的注解,可用于类或方法上。 |
@Autowired | 它可以对类成员变量方法及构造函数进行标注,完成自动装配的工怍。通过@Autowired的使用来消除 set . get方法 |
@PathVariable | 用于将清求UML中的模板变量映射到功能处理方法的参数上,即取出ur模板中的变量作为参数 |
@requestParam | 主要用于在SpringMVC后台控制层获取参致,类似一种是request.getParameter(“name”) |
@RequestHeadere | 可以把Request清求header邵分的值转定到方法的参数上 |
注解 | 说明 |
---|---|
@ModelAttribute | 该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在视用Controller时,先执行@ModelAttribute方法 |
@SessionAttributes | 即将值放到session作用域中,写在class上面 |
@valid | 实体数据仗验,可以结合hibernate validator一起使用 |
@CookieValuea | 用来获取Cookie中的值 |
8 Spring IOC 原理(控制反转)
8.1 IOC概念
Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean, 并建立 Bean 之间的依赖关系。
Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。
总结:
- 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,
通过容器来实现对象组件的装配和管理
。 - 谓的“控制反转”概念
就是对组件对象控制权的转移
,从程序代码本身转移到了外部容器
。 - Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
8.2 Bean注入流程(spring容器高层视图)
图例说明:
- Spring 启动时读取应用程序提供的 Bean 配置信息,
- 并在 Spring 容器中生成一份相应的 Bean 配置注册表,
- 然后根据这张注册表实例化 Bean,装配好 Bean 之间的依赖关系,为上层应用提供准备就绪的运行环境。
- 其中 Bean 缓存池为 HashMap 实现
8.3 IOC容器实现
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;
ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。
BeanFactory
下图为BeanFactory继承体系
图例说明:
-
BeanDefinitionRegistry注册表
Spring 配置文件中每一个节点元素在 Spring 容器里都通过一个 BeanDefinition 对象表示,它描述了 Bean 的配置信息。而BeanDefinitionRegistry 接口提供了向容器手工注册 BeanDefinition 对象的方法
。 -
BeanFactory 顶层接口
位于类结构树的顶端 ,它最主要的方法就是 getBean(String beanName)
,该方法从容器中返回特定名称的 Bean
,BeanFactory 的功能通过其他的接口得到不断扩展: -
ListableBeanFactory
该接口定义了访问容器中 Bean 基本信息的若干方法
,如查看 Bean 的个数、获取某一类型 Bean的配置名、查看容器中是否包括某一 Bean 等方法; -
HierarchicalBeanFactory父子级联
父子级联 IoC 容器的接口,子容器可以通过接口方法访问父容器
; 通过HierarchicalBeanFactory 接口, Spring 的 IoC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的 Bean,但父容器不能访问子容器的 Bean
。Spring 使用父子容器实现了很多功能,比如在Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的 Bean 位于父容器中。这样,展现层 Bean 就可以引用业务层和持久层的 Bean,而业务层和持久层的 Bean 则看不到展现层的Bean。
-
ConfigurableBeanFactory
是一个重要的接口,增强了 IoC 容器的可定制性
,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法; -
AutowireCapableBeanFactory 自动装配
定义了将容器中的 Bean按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法
; -
SingletonBeanRegistry运行期间注册单例Bean
定义了允许在运行期间向容器注册单实例 Bean 的方法
;
对于单实例( singleton)的 Bean 来说,BeanFactory 会缓存 Bean 实例,所以第二次使用 getBean() 获取 Bean 时将直接从 IoC 容器的缓存中获取 Bean 实例。
Spring 在 DefaultSingletonBeanRegistry 类中提供了一个用于缓存单实例 Bean 的缓存器,它是一个用 HashMap 实现的缓存器,单实例的 Bean 以 beanName 为键保存在这个 HashMap 中。 -
依赖日志框框
在初始化 BeanFactory 时,必须为其提供一种日志框架,比如使用 Log4J, 即在类路径下提供Log4J 配置文件,这样启动 Spring 容器才不会报错。
ApplicationContext 面向开发应用
ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用 的 功 能 。
ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能:如下图所示
图例说明
- ClassPathXmlApplicationContext:默认
从类路径
加载配置文件 - FileSystemXmlApplicationContext:默认
从文件系统
中装载配置文件 - ApplicationEventPublisher:
让容器拥有发布应用上下文事件的功能
,包括容器启动事件、关闭事件等。 - MessageSource:为应用
提供
i18n 国际化消息访问的功能
; - ResourcePatternResolver : 所 有ApplicationContext 实现类都实现了类似于
PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文路径装载 Spring 的配置文件。 - LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,
主要用于控制异步处理过程
。在具体使用时,该接口同时被 ApplicationContext 实现及具体Bean 实现,ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的。 - ConfigurableApplicationContext 扩展于ApplicationContext,它新增加了两个主要的方法:refresh()和 close(),
让ApplicationContext 具有启动、刷新和关闭应用上下文的能力
。在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用 close()则可关闭应用上下文
8.4 WebApplication 体系架构
WebApplicationContext 是专门为 Web 应用准备的,它允许从相对于 Web 根目录的路径中装载配置文件完成初始化工作
。从WebApplicationContext 中可以获得 ServletContext 的引用,整个 Web 应用上下文对象将作为属性放置到 ServletContext中,以便 Web 应用环境可以访问 Spring 应用上下文。
8.5 Spring 依赖注入四种方式
构造器注入
// 需要注入的bean
/*带参数,方便利用构造器进行注入*/
public CatDaoImpl(String message){
this. message = message;
}
// 配置文件内容
<bean id="CatDaoImpl" class="com.CatDaoImpl">
<constructor-arg value=" message "></constructor-arg>
</bean>
setter方法注入
// 需要注入的bean
public class Id {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
//配置文件内容
<bean id="id" class="com.id ">
<property name="id" value="123"></property>
</bean>
静态工厂注入
- 通过调用静态工厂的方法来获取自己需要的对象,为了让 spring 管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过 spring 注入的形式获取
public class DaoFactory {
//静态工厂
public static final FactoryDao
getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}
public class SpringAction {
private FactoryDao staticFactoryDao;
//注入对象
//注入对象的 set 方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
}
//factory-method="getStaticFactoryDaoImpl"指定调用哪个工厂方法
<bean name="springAction" class=" SpringAction" >
<!--使用静态工厂的方法注入对象,对应下面的配置文件-->
<property name="staticFactoryDao" ref="staticFactoryDao"></property>
</bean>
<!--此处获取对象的方式是从工厂类中获取静态方法-->
<bean name="staticFactoryDao" class="DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean>
实例工厂
- 实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先 new 工厂类,再调用普通的实例方法
public class DaoFactory {
//静态工厂
public static final FactoryDao
getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}
public class SpringAction {
private FactoryDao staticFactoryDao;
//注入对象
//注入对象的 set 方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
}
<bean name="springAction" class="SpringAction">
<!--使用实例工厂的方法注入对象,对应下面的配置文件-->
<property name="factoryDao" ref="factoryDao"></property>
</bean>
<!--此处获取对象的方式是从工厂类中获取实例方法-->
<bean name="daoFactory" class="com.DaoFactory"></bean>
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean>
8.6 Spring IoC 的实现机制
Spring 中的 IoC 的实现原理
就是工厂模式加反射机制
。
8.7 什么是Spring的依赖注入(DI)
控制反转IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入
和依赖查找依赖注
入
所谓依赖注入(Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中
。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。
8.8 依赖注入有什么优势
让容器全权负责依赖查询
,受管组件只需要暴露JavaBean的setter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:
- 查找定位操作与应用代码完全无关。
- 不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。
- 不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器
9 Spring如何处理线程并发问题?
Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理
,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
同步机制
采用了“时间换空间
”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。
而ThreadLocal
采用了“空间换时间
”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。
10 解释对象/关系映射集成模块
Spring 通过提供ORM模块,支持我们在直接JDBC之上使用一个对象/关系映射映射(ORM)工具,Spring支持集成主流的ORM框架
11 Spring支持的事务管理类型, spring 事务实现方式有哪些?
Spring支持两种类型的事务管理:
-
编程式事务管理:这意味你
通过编程的方式管理事务
,给你带来极大的灵活性,但是难维护。 -
声明式事务管理:这意味着你可以
将业务代码和事务管理分离
,你只需用注解和XML配置来管理事务
。
12 Spring事务的实现方式和实现原理
Spring事务的本质其实就是数据库对事务的支持
,没有数据库的事务支持,spring是无法提供事务功能的。
真正的数据库层的事务提交和回滚是通过 binlog或者redo log实现的。
13 spring 的事务隔离?
spring 有五大隔离级别,默认值为ISOLATION_DEFAULT(使用数据库的设置)
,其他四个隔离级别和数据库的隔离级别一致:
ISOLATION_DEFAULT
:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;- ISOLATION_READ_UNCOMMITTED:
未提交读
,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读); - ISOLATION_READ_COMMITTED:
提交读
,一个事
务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别; - ISOLATION_REPEATABLE_READ:
可重复读
,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别
; - ISOLATION_SERIALIZABLE:
序列化
,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
14 Spring APO 原理
AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一 些具有横切性质的系统级服务。
14.1 AOP 有哪些实现方式?
AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
AspectJ是静态代理的增强
,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类
,因此也称为编译时增强
,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。Spring AOP使用的动态代理
,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象
,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。