文章目录
1.spring整体架构
Core Container
核心容器,里面包含四部分
-
Beans 创建和管理Bean以及IOC,访问配置文件等
-
Core 核心工具类,是其它组件的基本核心,我们也可以自己使用
-
Context 构建于Core和Beans模块基础之上,为spring核心提供扩展,它的关键是ApplicationContext接口,添加了bean的生命周期控制等功能
-
Expression Language 提供了强大的表达式语言,用于在运行时查询和操纵对象
Data Access/Integration
包含五个模块
-
JDBC 对JDBC数据访问进行封装的所有类
-
ORM 对象-关系映射API
-
OXM 对Object/XML映射实现的抽象层
-
JMS Java Messaging Service 制造和消费消息的特性
-
Transaction 支持编程和声明性的事务管理
Web
建立在应用程序上下文模块之上,为基于Web的应用程序提供上下文,Web模块还简化了处理大部分请求以及将请求参数绑定到域对象的工作
-
Web 提供了基础的面向Web的集成特性
-
Web-Servlet 包含SpringMVC的实现
-
Web-Struts 对Struts支持,该支持在3.0弃用
-
Web-Prolet 提供了对Portlet环境和Web-Servlet模块的MVC实现
AOP
面向切面编程的实现,利用source-level的元数据功能,还可以将各种行为信息合并到代码中
- aop 核心模块,是AOP主要实现模块
- aspects 集成自AspectJ框架,提供多种AOP实现方法
- instructment 这个感觉也比较重要,程序员可以通过代理类在运行时修改类的字节,从而改变一个类的功能,实现AOP
Test
支持使用JUnit和TestNG对spring组件进行测试
依赖关系
2.Spring框架中获取连接池的四种方式
- DBCP数据源
- C3P0数据源
- spring的数据源实现类(DriverManagerDataSource)
- 获取JNDI数据源
3.spring三种注入方式
- 构造方法注入
- setter注入
- 接口注入
4.spring事务管理
- 编程式事务管理 灵活性强,但是难维护
- 声明式事务管理(使用) 将业务代码和事务管理分离,只需用注解和XML配置来管理事务,通过AOP实现
- @Transactional 注解只能应用到 public 可见度的方法上
- 建议在具体的类(或类的方法)上使用 @Transactional 注解,而不是接口上
- 默认情况下,如果被注解的数据库操作方法中发生了运行时异常,所有的数据库操作将rollback;如果发生的异常是checked异常,默认情况下数据库操作还是会提交的
- @Transactional注解的作用可以传播到子类,即如果父类标了子类就不用标了。但倒过来就不行了
- 在同一个类里,一个没有加注解的调用加注解的,被调用方法的事务也是不会生效的,因为内部调用不会调用切面的代理逻辑,如果想调用切面,可以考虑AopContext.currentProxy()这种方式。
5.spring事务传播行为
- PROPAGATION_REQUIRED(默认) 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中
- PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
- PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常
- PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起
- PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
- PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
- PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作
6.@Resource和@Autowire的区别
- @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
- @Resource 是JDK1.6支持的注解,默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
7.SpringMVC的工作流程
- ⑴用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
- ⑵DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回
- ⑶ DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
- ⑷提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
- HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
- 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
- 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
- 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
- ⑸Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象
- ⑹根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet
- ⑺ViewResolver 结合Model和View,来渲染视图
- ⑻将渲染结果返回给客户端
8.Spring涉及设计模式
⑴简单工厂模式
Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象
⑵工厂方法模式
Spring中的FactoryBean就是典型的工厂方法模式
⑶单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
Spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例
⑷适配器模式
Spring在拦截器上采用了适配器模式。
⑸装饰器模式
Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。
⑹代理模式
Spring的Proxy模式在aop中有体现
⑺观察者模式
Spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
⑻策略模式
Spring中在实例化对象的时候用到Strategy模式。
⑼模板方法模式
JdbcTemplate使用了模板方法模式。
9.IOC
⑴ 概述
IOC容器来负责控制对象和对象间依赖的关系。
⑵ 原理
IOC容器其实就是一个concurrenthashmap,它用来管理我们所有的对象及依赖关系,具体步骤:
- 通过反射我们可以获取类的所有信息(成员变量、类名等等等)
- 再通过配置文件(xml)或者注解来描述类与类之间的关系
- 最后我们通过这些配置信息和反射技术来构建出对应的对象和依赖关系了
10.AOP
⑴概述
AOP就是面向切面编程
⑵原理
基于动态代理技术,分为Java JDK动态代理和CGLIB动态代理。
①JDK动态代理
基于反射,被代理对象必须实现一个接口,只能对该类接口中定义的方法实现代理。
②CGLIB动态代理
字节码技术。利用asm开源包,把代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。采用非常底层的字节码技术,为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。
③两种代理的区别
- ⑴前者是基于反射技术,后者是基于字节码技术
- ⑵JDK的动态代理只能代理实现了接口的类,CGLib不能对声明为final的方法进行代理
- ⑶CGLib所创建的动态代理对象在实际运行时候的性能要比JDK动态代理高不少,但是随着JDK优化,JDK代理效率大大提高。
- 但是CGLib在创建对象的时候所花费的时间却比JDK动态代理要多很多;
- 对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理,反正,则比较适用JDK动态代理。
④AOP使用不同代理的时机
- 目标对象实现了接口,默认情况下会采用JDK的动态代理,但可以强制使用CGLIB代理
- 目标对象没有实现接口,使用CGLIB代理
11.spring、springMVC、springBoot和springCloud
- spring 基础是IOC和AOP,是springMVC和springBoot的基础
- springMVC spring基础上的MVC框架,主要解决 WEB 开发的问题
- springBoot 实现自动配置,降低项目搭建的复杂度
- springCloud 依赖springboot,主要用于微服务的整合管理
12.@Enable*注解的原理
从spring3.1开始支持@Enable模块驱动,举几个常见的例子:
@EnableAutoConfiguration // 开启自动装配
@EnableScheduling // 开启计划任务
当我们进入@Enable*注解,都会发现一个@Import注解,这个注解的作用是将指定类的实例注入到IOC容器中,它分为三种方式,分别为:
- 直接导入配置类
- 根据条件选择配置类
- 动态注册Bean
13.DefaultListableBeanFactory
是整个bean加载的核心部分,是Spring注册及加载bean的默认实现
14.XmlBeanDefinitionReader
读取XML配置文件
15.spring bean继承结构
16.编程式使用IOC容器
ClassPathResource res = new ClassPathResource("beans .xml");//定位
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);//开始载入的入口函数,载入完就注册