spring
什么是spring
Spring框架是一个为Java应用程序开发提供综合、广泛的基础性支持的Java平台。Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring框架本身也是按照设计模式精心打造的,这使得我们可以在开发环境中安心地集成Spring框架,不必担心Spring是如何在后台工作的。
Spring框架的优点
● 非侵入式设计
Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。
● 方便解耦、简化开发
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器管理,大大的降低了组件之间的耦合性。
● 支持AOP
Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事务、日志等进行集中式处理,从而提高了程序的复用性。
● 支持声明式事务处理
只需要通过配置就可以完成对事务的管理,而无需手动编程。
● 方便程序的测试
Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序。
● 方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持。
● 降低Java EE API的使用难度
Spring对Java EE开发中非常难用的一些API(如:JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。
spring构成模块
Spring 总共大约有 20 个模块, 由 1300 多个不同的文件构成。 而这些组件被分别整合在核心容器模块(spring core)、应用上下文模块(spring context)、AOP模块(spring aop)、JDBC抽象和DAO模块(spring dao)、对象/关系映射集成模块(spring orm)、Web模块(spring web)、MVC模块(spring mvc)
- 容器模块(spring core)
这是Spring框架最基础的部分,它提供了依赖注入(DependencyInjection)特征来实现容器对Bean的管理。核心容器的主要组件是 BeanFactory,BeanFactory是工厂模式的一个实现,是任何Spring应用的核心。它使用IoC将应用配置和依赖从实际的应用代码中分离出来 - 应用上下文模块(spring context)
核心模块的BeanFactory使Spring成为一个容器,而上下文模块使它成为一个框架。这个模块扩展了BeanFactory的概念,增加了对国际化(I18N)消息、事件传播、验证的支持
这个模块提供了许多企业服务,例如电子邮件、JNDI访问、EJB集成、远程以及时序调度(scheduling)服务。也包括了对模版框架例如Velocity和FreeMarker集成的支持 - AOP模块(spring aop)
Spring在它的AOP模块中提供了对面向切面编程的丰富支持,Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中,可以自定义拦截器、切点、日志等操作 - JDBC抽象和DAO模块(spring dao)
提供了一个JDBC的抽象层和异常层次结构,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC - 对象/关系映射集成模块(spring orm)
Spring提供了ORM模块。Spring并不试图实现它自己的ORM解决方案,而是为几种流行的ORM框架提供了集成方案,包括Hibernate、JDO和iBATIS SQL映射,这些都遵从 Spring 的通用事务和 DAO 异常层次结构 - Web模块(spring web)
Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文,提供了Spring和其它Web框架的集成,比如Struts、WebWork。还提供了一些面向服务支持,例如:实现文件上传的multipart请求 - MVC模块(spring mvc)
Spring为构建Web应用提供了一个功能全面的MVC框架。虽然Spring可以很容易地与其它MVC框架集成,例如Struts,但Spring的MVC框架使用IoC对控制逻辑和业务对象提供了完全的分离
优点
核心IOC
读作**“反转控制”(Inverse of Control)更好理解,不是什么技术,而是一种 设计思想,就是**将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。
对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。
正控:若要使用某个对象,需要自己去负责对象的创建
反控:若要使用某个对象,只需要从 Spring 容器中获取需要使用的对象,
不关心对象的创建过程,也就是把创建对象的控制权反转给了 Spring 框架.
AOP
- oop 为面向对象编程(在oop基础上增加功能),将业务代码(保存,删除)和非业务代码(保存日志,提交事务)分离
oop是整体设计
AOP是针对业务代码中的公共部分提取,
核心原理: 使用动态代理的方式在执行方法前后或者出现异常的时候做加入相关的逻辑,可实现在不修改代码的情况下为程序增加新功能
抽取代码有条件(功能和业务逻辑没有直接关系)
面向切面编程的好处就是: 减少重复,专注业务;
注意:面向切面编程只是面向对象编程的一种补充。
使用动态代理的方式在执行方法前后或者出现异常的时候做加入相关的逻辑.
事务处理:开启事务,关闭事务,出现异常后回滚事务
权限判断:在执行方法前,判断是否具有权限
日志:在执行前进行日志处理
**连接点(Joinpoint):**类中可以被增强的方法,这个方法就被称为连接点
**切入点(pointcut):**类中有很多方法可以被增强,但实际中只有 add 和 update被增了,那么 add 和 update 方法就被称为切入点(实际实现的连接点)
通知(Advice): 通知是指一个切面在特定的连接点要做的事情(增强的功能)。通 知分为方法执行前通知,方法执行后通知,环绕通知等.
**切面(Aspect)😗*把通知添加到切入点的过程叫切面.
目标(Target): 代理的目标对象(要增强的类)
代理(Proxy): 向目标对象应用通知之后创建的代理对象
spring容器创建对象的时机
scope 单例 原型
依赖注入方式 xml 注解
注解优点: 方便,直观,高效(代码少,没有配置文件的书写那么复杂)。
**注解缺点:**以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。
xml 优点是: 配置和代码是分离的,在 xml 中做修改,无需编译代码,只需重 启服务器即可将新的配置加载。
**xml 的缺点是:**编写麻烦,效率低,大型项目过于复杂。
@Autowired 与@Resource的区别
@Autowired//默认按type注入 , Spring提供的注解
@Qualifier(“userDao”)//一般作为@Autowired()的修饰用 按照对象名注入
UserDao userDao;
@Resource(name=“cusInfoService”)//默认按name注入,可以通过name和type属性进行选择性注入, jdk提供
UserDao userDao;
spring事务管理
声明式事务(使用 AOP的基础上增强了事务管理)
管理建立在 AOP 基础上,本质是对方法前后进行拦截,所以声明式 事务是方法级别的。
基于 xml 配置 基于注解实现
Spring 针对不同的 dao 框架,提供了不同的实现类,Jdbc,mybatis 事物管理实 现类是DataSourceTransactionManager.
编程式事务
在 项 目 中 很 少 使 用 , 这 种 方 式 需 要 注 入 一 个 事 务 管 理 对 象 TransactionTemplate ,然后在我们代码中需要提交事务或回滚事务时自己写代 码实现.
说一下 spring 的事务传播行为
即然是传播,那么至少有两个东西,才可以发生传播。单体不存在传播这个行为。
事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事
务方法调用时,这个事务方法应该如何进行。事务传播行为是 Spring 框架独有
的事务增强特性,他不属于的事务实际提供方数据库行为.
例如:methodA 事务方法调用 methodB 事务方法时,methodB 是继续在调
用者 methodA 的事务中运行呢,还是为自己开启一个新事务运行,这就是由
methodB 的事务传播行为决定的。
Spring 定义了七种传播行为:
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务,指定的方法必须在事务内执行,若当前存在事务,加入到当前事务中,若当前没 有事务,则创建一个新事务,这种传播行为是最常见的,也是 spring 默认的传播行 为.
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPOR TED
以非事务方式执行操作,如果当前存在事务,就把当前事务 挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事 务,则执行与 PROPAGATION_REQUIRED 类似的操作。
声明式事务不生效的场景
@Transactional 应用在非 public 修饰的方法上
@Transactional 注解属性 propagation 设置错误
同一个类中方法调用,导致@Transactional 失效
异常被 catch 捕获导致@Transactional 失效
数据库引擎不支持事务
BeanFactory和ApplicationContext
首先,BeanFactory与ApplicationContext是spring的两大核心接口,都可以当做spring的容器。
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;
ApplicationContext 面向使用Spring 框架的开发者, ApplicationContext 使用的“场合”较多
一、功能上的区别
BeanFactory是Spring中最底层的接口,是IOC的核心,其功能包含了各种Bean的定义、加载、实例化、依赖注入和生命周期的管理。是IOC最基本的功能。
而ApplicationContext接口是BeanFactory的子类,具有BeanFactory所有的功能,同时继承了MessageSource,所以提供了更完整的框架功能,支持国际化、资源文件访问、载入多个上下文配置文件,使得每一个上下文都专注于一个特定层次,提供在监听器中注册bean事件。
二、加载方式的区别
BeanFactory是延时加载,也就是说在容器启动时不会注入bean,而是在需要使用bean的时候,才会对该bean进行加载实例化。
ApplicationContext 是在容器启动的时候,一次性创建所有的bean,所以运行的时候速度相对BeanFactory比较快。
*因为加载方式的不同,导致BeanFactory无法提前发现spring存在的配置问题。(如果bean的某个属性没有注入,BeanFactory加载不会抛出异常,直至第一次调用getBean()方法时才会抛出异常。)但是ApplicationContext 在容器启动时就可以发现spring存在的配置问题,因为他是一次性加载的,有利于检测依赖属性是否注入(也因为其一次性加载的原因,导致占用内存空间,当Bean较多时,影响程序启动的速度)。
三、创建方式的区别
BeanFactory是以编程的方式创建的。
ApplicationContext 是以声明的方式创建的。
四、注册方式的区别
BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用
BeanFactory是需要手动注册的。 ApplicationContext 是自动注册的。
springBean的生命周期
实例化(Instantiation)
属性赋值(Populate)
初始化(Initialization)
销毁(Destruction)
对象创建
1,从xml配置的Bean,@Bean注解,或者Java代码BeanDefinitionBuilder中读取Bean的定义,实例化Bean对象;
2,设置Bean的属性;
3,注入Aware的依赖(BeanNameAware,BeanFactoryAware,ApplicationContextAware);
4, 执行通用的方法前置处理,方法: BeanPostProcessor.postProcessorBeforeInitialization()
5, 执行 InitalizingBean.afterPropertiesSet() 方法
6,执行Bean自定义的初始化方法init,或者 @PostConstruct 标注的方法;
7,执行方法BeanPostProcessor.postProcessorAfterInitialization()
8, 创建对象完毕;
对象销毁
9, 执行 DisposableBean.destory() 方法;
10,执行自定义的destory方法或者 @PreDestory 标注的方法;
11,销毁对象完毕
Spring 中的bean 是线程安全的吗?
Bean循环依赖
Spring MVC 运行流程
用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器);
由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)。
DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View
视图中的 request 域,生成最终的 View(视图);
视图负责将结果显示到浏览器(客户端)。
Spring MVC的常用注解解释
@Controller
@RequestMapping
Servlet的过滤器与Spring拦截器详解
实现原理不同
过滤器和拦截器 底层实现方式大不相同,过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。
使用范围不同
我们看到过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
触发时机不同
过滤器 和 拦截器的触发时机也不同,我们看下边这张图。
过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。
拦截的请求范围不同
过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。
springBoot
什么是springboot
在spring的基础上进行开发的,
解决spring问题: 依赖多,模板化的配置
搭建非常方便
起步依赖 直接将相关的jar包直接进行依赖
自动装配
springboot如何实现自动装配
注解
配置
根据在配置文件中配置,自动扫描加载组件
扫描
@Component和@Bean的区别
@Component用在类上 创建该类的对象,并管理
@Bean用在方法
public User {
return new User();
}