前段时间的认定让我觉得开始总结知识点迫在眉睫,先从Spring开始吧,注意,这里的Spring 就是指Spring framework,为了方便,就写成了Spring,整个Spring生态相当庞大,详情可见Spring官网
Spring基础
Spring的基本概念及其特点
- Spring是一个轻量级Java开发框架
- Spring的设计理念:在JavaEE开发中,支持POJO和JavaBean开发方式,使得应用面向接口开发,尽可能利用OO的设计思想
- Spring框架的核心:IoC和AOP。通过IoC容器管理POJO对象以及对象之间的耦合关系;通过AOP以动态非侵入的方式增强服务
优点
- 耦合度很低
- AOP功能强大,面向切面编程,便于对程序进行监控、拦截等
- 声明式事务支持,只要配置即可完成对事务的管理
- 测试方便,已经支持Junit4
- 便于集成各种优秀的框架,比如Struts、Hibernate、MyBatis等
- 封装强大,使得JavaEE API的使用难度大大降低
缺点
- 入门难度不低(至少给我的感觉是这样的
- Spring的目标是实现轻量开发,但数量上并不少
- Spring比较依赖反射,而反射的性能一般
Spring的模块构成
主要是七大模块:核心容器(Core Container)、AOP(ASPECT Oriented Programming)和设备支持(Instrmentation)、数据访问与集成(Data Access/Integeration)、Web、Messaging、Test
- Spring Core:个人认为最基础也是最重要的部分,包括IoC(Inversion of Control)和DI(Dependency Injection)
- Spring Beans:提供了BeanFactory,工厂模式的经典实现,被Spring管理的对象统称为Bean
- Spring context:基于core封装包封装的context,提供了一种框架式的对象访问方法
- Spring jdbc:JDBC抽象层,用于简化JDBC的繁琐操作
- Spring AOP:提供面向切面的编程实现
- Spring Web:提供了针对Web开发的集成特性
- Sping test:支持用JUnit或者TestNG对Spring组件进行单元测试和集成测试
Spring框架中都用到了哪些设计模式
- 工厂模式:BeanFactory即为简单工厂模式的体现,用于创造对象的实例
- 单例模式:Bean默认单例模式
- 代理模式:Spring的AOP用的是JDK的动态代理和CGLIB字节码生成技术
- 模板方法:提高代码复用率,如:RestTemplate、RedisTemplate
- 观察者模式:定义一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并更新,比如Spring种listener的实现——ApplicationListener
Spring框架中有哪些不同类型的事件
Spring提供了以下5种标准的事件:
- 上下文更新事件:ConfigurableApplicationContext .refresh()
- 上下文开始事件:ConfigurableApplicationContext .start()
- 上下文停止事件:ConfigurableApplicationContext .stop()
- 上下文关闭事件:ApplicationContext被关闭时触发,且关闭时所有的单例Bean都被销毁
- 请求处理事件:Web应用中,当一个http请求结束触发该事件,如果一个Bean实现了ApplicationListener接口,当一个ApplicationEvent被发布以后,Bean会自动被通知
Spring控制反转(IoC)
IoC是什么?
IoC将传统上由程序代码直接操控的对象的调用权较给容器,通过容器来实现对象组件的装配和管理,“控制反转”的概念就是对组件对象的控制权的转移,从程序本代码本身转移到了外部容器IoC负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期
IoC有什么作用
- 管理对象的创建和依赖关系的维护
- 代理,不用程序员关心类的产生
IoC优点
- 降低应用代码量
- 便于单元测试
- 侵入性小,松散耦合得以实现
- IoC容器支持加载服务时的饿汉式初始化和懒加载
IoC的实现机制
工厂模式加反射机制
Spring IoC支持什么功能
- 依赖注入
- 依赖检查
- 自动装配
- 支持集合
- 指定初始化方法和销毁方法
- 支持回调某些方法
什么是依赖注入
主要实现方式:依赖注入和依赖查找
由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中
依赖注入的基本原则
应用组件不应该负责查找自愿或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责
依赖注入的优势
容器全权负责查询,受管组件只需要暴露JavaBean的setter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系,跟依赖查找相比,主要优势为:
- 查找定位操作与应用代码完全无关
- 不依赖于容器的API
- 不需要特殊接口,绝大多数对象可以做到完全不依赖容器
有哪些不同类型的依赖注入实现方式
接口注入(Interface Injection),Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式
- 接口注入的灵活性和易用性比较差,从Spring4开始已被废弃
- 构造器依赖注入:通过容器触发一个类的构造器来实现
- Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂方法实例化Bean之后,调用该Bean的setter方法
SpringBeans
什么是SpringBeans
Spring Beans是那些形成Spring应用的主干的Java对象,被IoC容器初始化、装配、管理,一个Spring Bean的定义包含容器必知的所有配置元数据,包括如何创建一个Bean,它的生命周期详情及它的依赖
给Spring容器提供配置元数据的方式
- XML配置文件
- 基于注解的配置
- 基于Java的配置
Spring基于xml注入Bean的几种方式
- Set方法注入
- 构造器注入:A.通过index设置参数位置;B.通过type设置参数类型
- 静态工厂注入
- 实例工厂
Spring支持的几种Bean的作用域
通过Bean定义中的scope属性来定义Bean的作用域
- singleton:Bean在每个IoC容器中只有一个实例
- prototype:一个Bean的定义可以有多个实例
- request:每次http请求都会创建一个Bean,仅在web的Spring ApplicationContext情形下有效
- session:在HTTP Session中,一个Bean定义对应一个实例,仅在基于web的Spring ApplicationContext情形下有效
- global-session:全局的HTTP Session
Spring框架中的单例Bean是线程安全的吗
答案:不是
Spring中的Bean默认都是单例模式,Spring框架并没有对单例Bean进行多线程的封装处理,Bean状态改变时需要开发者自行去保证线程安全
Spring如何处理线程并发问题
只有无状态的Bean才可以在多线程环境下共享,对一些Bean中非线程安全状态财用ThreadLocal进行处理,以解决线程安全问题
Spring中Bean的生命周期
图,待补充
Bean重要的生命周期方法,是否可重载
setup:容器加载Bean的时候被调用
teardown,容器卸载类的时候被调用
Spring的内部Bean
在Spring中,当一个Bean仅被用于作另一个bean的属性时,它能被声明为一个内部Bean,内部Bean可以用setter方法注入,通常是匿名的,Scope一般是prototype
Bean的自动装配
在配置文件中设定好Bean的依赖关系,随后Spring容器能够自动装配相互合作的Bean
Spring自动装配Bean的方式
- no:默认不进行自动装配,手动设置ref属性来装配Bean
- byName:通过Bean的名字来进行自动装配
- byType:通过参数的数据类型来自动装配
- constructor:利用构造函数进行装配,构造函数的参数通过byType进行装配
- autodetect:自动探测,如果有构造方法则通过construct的方式自动装配,否则使用byType的方式自动装配
使用@Autowired注解自动装配的过程
- 开琪注解,必须先在Spring配置文件进行配置
- 扫描查询:启动Spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,扫描到@Autowirid、@Resource或者@Inject时,会在IoC容器自动查询需要的bean,并装配给该对象的属性,在容器中首先查询对应类型的Bean:
如果查询结果刚好为一个,则装配给注解指定的数据
如果不止一个,根据名称来查找
如果为空,抛出异常,解决方法可以令required = false
注解
如何开琪注解装配
注解装配在默认情况下不开启,为了使用注解装配,我们必须在Spring配置文件中配置context:annotation-config/元素
@Component,@Controller,@Repository,@Service有何区别
@Component:将Java类标记为Bean,是任何Spring管理组件的统用构造型,Spring的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中
@Controller:将类标记为Spring Web MVC控制器,标有这个注解的Bean会自动导入IoC容器中
@Service:组件注解的特化,不会对@Component注解提供任何其他行为,可以在服务类中使用@Service而不是@Conponent,这样的用意更加明显
@Repository:为DAO层提供了额外的检查,将DAO导入IoC容器,可以使未经检查的异常有资格转换为Spring DataAccessException
@Required 注解有什么用
表面Bean的属性必须在配置的时候设置,通过一个Bean定义的显示的属性值或通过自动装配,如果@Required注解的Bean属性未被设置,容器会抛出BeanInitializationException
@Autowired 注解有什么用
@Autowired默认按照类型进行装配注入,默认情况下要求依赖对象必须存在(或者设置required属性为false),可修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法
@Autowired和@Resource之间的区别
@Autowired按照类型进行注入,默认情况下要求依赖对象必须存在(或者设置required属性为false)
@Resource默认按照名称来装配注入,找不到名称匹配的Bean才会按照类型进行注入
@Qualifier 注解有什么用
创建多个相同类型的Bean并希望仅使用属性装配其中一个Bean时,可以使用@Qualifier注解和@Autowired通过指定应该装配哪个确切的Bean来消除歧义
@RequestMapping 注解有什么作用
用于将特定HTTP请求方法映射到将处理相应请求的控制器中的特定类/方法,可以应用于类(映射请求的URL)或者是方法(HTTP请求方法)
数据模块
解释对象/关系映射集成模块
Spring通过提供ORM模块,支持在JDBC之上使用一个对象/关系映射工具(ORM),Spring支持集成主流的ORM框架,如Hiberate,JDO和iBATIS,JPA,TopLink,JDO,OJB,Spring的事务管理同样支持以上所有ORM框架以及JDBC
Spring DAO有什么用
Spring DAO使得JDBC,Hibernate或JDo这样的数据访问技术更容易以一种统一的方式工作,这使得用户容易在持久性技术之间切换,也不用刻意捕获每种技术不同的异常
Spring通过什么方式访问Hibernate?使用Spring访问Hibernate的方法有哪些
- 使用Hibernate模板和回调进行控制反转
- 扩展HibernateDAOSupport并应用AOP拦截器节点
面向切面编程(AOP)
什么是AOP
将与业务无关,但对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块就叫切面(Aspect),减少系统中的重复代码,降低系统耦合度,一般用于权限认证、日志、事务处理等等
Spring AOP 和 Aspect AOP的区别?AOP有哪些实现方式
AOP实现的关键点是代理模式,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ,动态代理则以Spring AOP为代表
- AspectJ是静态代理的增强,所谓静态代理,是AOP框架会在编译阶段生成AOP代理类,因此也成为编译时增强,会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象
- Spring AOP使用的动态代理,即使AOP框架不会去修改字节码,而是每次匀性时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
Spring AOP里面的几个名词
- 切面(Aspect):切面是通知和切点的结合,一般以@AspectJ注解来实现
- 连接点(Join point):指方法,在Spring AOP中,一个连接点总是代表一个方法的执行。应用可能有数以千计的时机应用通知,这些时机被称为连接点。
- 通知(Advice):AOP术语中,切面的工作被称为通知
- 切入点(PointCut):切点的定义会匹配通知所要织入的一个或多个连接点,一般使用明确的类和方法名称,或者是正则表达式定义所匹配的类和方法名称来指定这些切点
- 引入(Intruduction):引入允许我们向现有类添加新方法或属性
- 目标对象(Target Object):被一个或者多个切面(Aspect)所通知(advise)的对象
- 织入(Weaving):植入是把切面应用到目标对象并创建新的代理对象的过程
Spring通知
在AOP中,切面的工作被称为通知,实际上是程序执行时要通过SpringAOP框架触发的代码段
- 前置通知(Before):在目标方法被调用之前调用通知功能
- 后置通知(After):在目标方法完成之后调用通知,此使不回关心方法的输出是什么
- 返回通知(After-returning):在目标方法成功执行之后调用通知
- 异常通知(After-throwing):在目标方法抛出异常后调用通知
- 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前合调用之后执行自定义的行为