一些Spring、SpringMVC、SpringBoot学习笔记
目录
2. @Controller和@Restcontroller
4. @Autowire 和 @Resource(装配Bean)
Spring
一、bean
1.bean的生命期
bean的生命周期从创建到销毁分为四个阶段:
实例化(Instantiation)
属性赋值(Populate)
初始化(Initialization)
销毁(Destruction)
大致的流程是
⭐️进行Bean的实例化后,
⭐️将Bean的 引入和 值 注入到Bean的属性中,
⭐️然后检查Aware相关接口并设置相关依赖,像BeanNameAware、BeanClassLoaderAware【 2. Bean实例化后对将Bean的引入和值注入到Bean的属性中 3. 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法 4. 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入 5. 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。 6. 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。 】,
⭐️在调用“BeanPostProcessor的前置处理”之后,
⭐️会接着检查当前对象是否实现了InitializingBean接口,
⭐️或者说是否配置自定义的init-method
⭐️再到BeanPostProcessor的后置处理
⭐️最后到销毁,与初始化相对应,会检查是否实现了DisposableBean接口和自定义的destroy-method,如果有的话则调用对应的方法。
至此,bean的生命周期就结束啦。
2.bean的scope —— bean的作用域
有五种scope类型:
singleton : 单实例,在一个容器中只存在一个共享且唯一bean实例,Spring 中的 bean 默认都是单例的。
prototype : 多实例,每次请求都会创建一个新的 bean 实例。
还有三种scope类型只适用于Web应用程序,分别是:
request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
global-session: 全局 session 作用域,仅仅在基于 Portlet 的 web 应用中才有意义,Spring5 已经没有了。Portlet 是能够生成语义代码(例如:HTML)片段的小型 Java Web 插件。它们基于 portlet 容器,可以像 servlet 一样处理 HTTP 请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。
registerScope方法就是Spring容器用来注册新的作用域,该方法有两个参数,第一个是与作用域相关的全局唯一名称,第二个参数是准备实现的作用域实例,即实现Scope接口的实例;使用自定义的Scope,开发者可以通过编程的方式来实现自定义Bean作用域,也可以通过XML配置和使用自定义作用域
二、IOC
1. IOC概念
什么是IOC?
IOC:控制反转,把创建对象过程交给Spring进行管理,获得依赖对象的过程由自身管理变为了由IOC容器主动
注入。
在具体的实现中,主要由三种注入方式:
1. 构造方法注入;对象在构造完成之后,即已进入就绪状态,可以马上使用。
2. setter方法注入;在对象构造完成后再注入,setter方法可以被继承,允许设置默认值。
3. 接口注入;带有侵入性,它强制被注入对象实现不必要的接口。被注入对象如果想要注入依赖对象,就
必须实现某个接口。这个接口提供一个方法,用来为其注入依赖对象。
---什么反转了:即获得依赖对象的过程被反转了,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。
---实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
---IOC中最基本的技术就是“反射(Reflection)”编程
2. IOC容器
Spring提供了两种容器类型:BeanFactory和ApplicationContext。
1. BeanFactory : 默认采用延迟初始化策略(lazy-load),在获取对象时才会去创建对象。所以,相对来
说,容器启动初期速度较快,所需要的资源有限。
2. ApplicationContext : 在容器启动之后,对象默认全部初始化并绑定完成。所以,相对于BeanFactory来
说,ApplicationContext要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之
BeanFactory也会长一些。
---BeanFactory: IOC容器基本实现,是Spring内部接口,不提供开发人员进行使用;
---ApplicationContext: BeanFactory接口的子接口,提供更多更强大的功能,比如事件发布、国际化信息
支持等,一般由开发人员进行使用;
三、AOP
⭐️AOP是什么:
AOP即面向切面编程,是OOP(面向对象编程)开发模式的一种补足,它可以去解决像日志记录、权限控制这
类在系统各处散落的系统需求的问题。底层实现是通过JDK动态代理或CGLib代理【在】【运行时期】在
【对象初始化】阶段织入代码。
⭐️涉及到一些概念:
aspect 切面: 切面由切点和增强(或引介 或通知)组成
joinpoint 连接点: 在系统上可以进行织入操作的执行点(将AOP功能模块织入OOP的功能模块的过程中,
进行织入操作的系统执行点就称为连接点,)常见的连接点类型有 方法调用、方法执行、异常处理。
pointcut 切点 : 切面在哪里作用,切点就是定义了在哪些连接点上执行,它连接点的表述方式,当我们将横切逻辑织入系统时,需要参照切点给出的连接点信息,去对应的连接点上织入横切逻辑。
advice 通知(增强) : 切面要做的工作,即在什么时候做什么
weaving 织入 : 织入是把切面应用到目标对象并创建新的代理对象的过程。
target 目标对象
aop proxy 代理对象
⭐️连接点和切点的区别:
能不能简单说下AOP中的切面、切点、连接点、通知,四者的关系?
织入指的是将 Advice 织入到 Pointcut 指定的 Joinpoint 处。
切点其实就是定义了需要执行在哪些连接点上执行通知。
切点就是定义了在哪些连接点上执行通知
⭐️AOP原理:
Spring AOP就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK
Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候
Spring AOP会使用Cglib生成一个被代理对象的子类来作为代理。
⭐️spring AOP使用场景,有什么注解?
场景:
日志记录
权限验证
事务处理
效率检查
异常处理
缓存处理
内容分发
⭐️动态代理区别:
JDK动态代理基于接口实现
CGLib基于类的继承实现
⭐️Spring AOP 和 AspectJ AOP 有什么区别?
Spring AOP 属于运行时增强
AspectJ 是编译时增强。
四、Spring事务
⭐️Spring支持两种方式的事务管理:
.编程式事务管理
通过 TransactionTemplate 或者 TransactionManager 手动管理事务,实际应用中很少使用
.声明式事务管理
推荐使用(代码侵入性最小),实际是通过 AOP 实现(基于 @Transactional 的全注解方式使用最多)
⭐️@Transactional 注解使用详解
作用范围
方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public方法上,否则不生效。
类 :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。
接口 :不推荐在接口上使用。
常用配置参数
propagation 事务的传播行为,默认值为 REQUIRED,可选的值在上面介绍过
isolation 事务的隔离级别,默认值采用 DEFAULT,可选的值在上面介绍过
timeout 事务的超时时间,默认值为-1(不会超时)。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 指定事务是否为只读事务,默认值为 false,默认读写。
rollbackFor 用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型。
(个人习惯喜欢写在代码段里,但是csdn检测全是代码不让发,所以无奈之举又重复一遍。)
⭐️Spring支持两种方式的事务管理:
.编程式事务管理
通过 TransactionTemplate 或者 TransactionManager 手动管理事务,实际应用中很少使用
.声明式事务管理
推荐使用(代码侵入性最小),实际是通过 AOP 实现(基于 @Transactional 的全注解方式使用最多)
⭐️@Transactional 注解使用详解
作用范围
方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public方法上,否则不生效。
类 :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。
接口 :不推荐在接口上使用。
常用配置参数
propagation 事务的传播行为,默认值为 REQUIRED,可选的值在上面介绍过
isolation 事务的隔离级别,默认值采用 DEFAULT,可选的值在上面介绍过
timeout 事务的超时时间,默认值为-1(不会超时)。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 指定事务是否为只读事务,默认值为 false,默认读写。
rollbackFor 用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型。
1. Spring 事务中有哪几种事务传播行为?
2. Spring事务的隔离级别
SpringMVC
SpringMVC是一个基于mvc的web框架,
Model(模型):数据模型,提供要展示的数据;
View(视图):负责进行模型的展示;
Controller(控制器):处理用户交互部分;
一、SpringMVC执行流程
1. 客户端发送请求给DispatcherServlet前端控制器
2. DispatcherServlet根据请求调用HandlerMapping处理器映射器
3. HandlerMapping解析请求对应的Handler,返回一个执行链
4. DispatcherServlet将执行链返回的Handler信息发给HandlerAdapter处理器适配器
5. HandlerAdapter会调用对应的Handler处理器(即Controller)
6. Handler执行完成后,会返回一个ModelAndView对象给HandlerAdapter
7. HandlerAdapter将接收到的ModelAndView对象返回给DispatcherServlet
8. DispatcherServlet根据ModelAndView对象选择合适的ViewResolver视图解析器
9. ViewResolver根据逻辑View返回实际的view给DispatcherServlet
10. DispatcherServlet对View进行渲染
11. 将视图渲染结果返回给浏览器(客户端)
⭐️总的说:
客户端发送请求到前端控制器,前端控制器调用处理器映射器,请求获取Handler;
处理器映射器跟据请求url找到具体的Handler,返回一个执行链给前端控制器;
前端控制器将执行链返回的Handler信息发给处理器适配器,请求执行Handler;
处理器适配器会 调用 对应的Handler处理器执行(即Controller);
当Handler执行完成后,会返回一个ModelAndView对象给处理器适配器,再返回到前端控制器;
前端控制器将收到的ModelAndView传给视图解析器进行解析;
视图解析器根据逻辑视图名解析成物理视图名,再⽣成View视图对象返回
最后前端控制器对View进行渲染,并将渲染结果返回给客户端。
⭐️涉及的五大组件:
1. DispatcherServlet:前端控制器,用于请求到达前端控制器,由它调用其他组件处理用户的请求。
前端控制器。⽤户请求到达前端控制器,它就相当于MVC模式中的C,DispatcherServlet是整个流程控制的
中⼼,由它调⽤其它组件处理⽤户的请求,DispatcherServlet的存在降低了组件之间的耦合性,系统扩展性
提⾼。
---由它调用其他组件处理用户的请求。
2. HandlerMapping:处理器映射器,负责根据用户请求找到Handler(处理器),springmvc提供了不同的映
射器实现方式。
处理器映射器。根据⽤户的请求地址来找到对应的Handler即控制器,spring mvc提供了不同的映射器实现
不同的映射⽅式,分别有:
xml配置⽅式
实现接⼝⽅式
注解⽅式
---根据用户请求找到Handler
3. HandlerAdapter:处理器适配器,通过HandlerAdapter对处理器进行执行。
处理器适配器。按照特定的规则去执行Handler,通过HandlerAdapter执行处理器。
---通过HandlerAdapter对处理器进行执行。
4. Handler:后端控制器(处理器),对具体的用户请求进行处理。
Handler 是DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体
的⽤户请求进⾏处理。由于Handler涉及到具体的⽤户业务请求,所以⼀般情况需要程序员根据业务需求开发
Handler。也就是我们常说的控制器类和方法。
---对具体的用户请求进行处理。
5. View Resolver:视图解析器,负责将处理结果生成view视图。
ViewResolver负责将处理结果⽣成View视图,ViewResolver⾸先根据逻辑视图名解析成物理视图名即具体
的页⾯地址,再⽣成View视图对象,最后对View进⾏渲染将处理结果通过页⾯展⽰给⽤户。
SpringBoot
一、SpringBoot自动配置
SpringBoot启动的时候先加载主程序类(主程序类也叫主配置类),主程序类被@SpringBootApplication标注,查看此注解源码我们发现,此注解是由以下三个注解组成:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
1.
@SpringBootConfiguration -- 配置类
点进去@SpringBootConfiguration,发现被@Configuration标注,这也说明:主程序类也是一个配置类。
再里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
2.
@ComponentScan -- 指定包的扫描范围
是一个Spring的注解,用来指定包的扫描范围
3.
@EnableAutoConfiguration -- 核心注解,开启了自动配置功能
SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration。此注解也是SpringBoot自动配置的核心注解,并且也是一个合成注解!
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
3.1
@AutoConfigurationPackage
@AutoConfigurationPackage里面的@Import(AutoConfigurationPackages.Registrar.class)
利用registrar给容器来批量注册组件,
指定包的默认规则
3.2
@Import(AutoConfigurationImportSelector.class)
getAutoConfigurationEntry(annotationMetadata)
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
总的说:
Spring Boot通过@EnableAutoConfiguration注解开启自动配置,通过 @Import 注解导入
AutoConfigurationImportSelector类,然后通过AutoConfigurationImportSelector 类的
selectImports 方法去加载spring.factories中注册的各种AutoConfiguration类,当某个
AutoConfiguration类满足其注解@Conditional指定的生效条件(Starters提供的依赖、配置或Spring容器
中是否存在某个Bean等)时,实例化该AutoConfiguration类中定义的Bean(组件等),并注入Spring容器,
就可以完成依赖框架的自动配置。
一定要记得XxxxProperties类的含义是:封装配置文件中相关属性;
XxxxAutoConfiguration类的含义是:自动配置类,目的是给容器中添加组件;
而其他的主方法启动,则是为了加载这些五花八门的XxxxAutoConfiguration类;
一些注解
1. @RequestMapping注解
@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。
@RequestMapping标识一个类:设置映射请求的请求路径的初始信息
@RequestMapping标识一个方法:设置映射请求请求路径的具体信息
☀️@RequestMapping注解的value属性
value属性通过请求的请求地址匹配请求映射
value属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求
value属性必须设置,至少通过请求地址匹配请求映射
☀️@RequestMapping注解的method属性
method属性通过请求的请求方式(get或post)匹配请求映射
method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配多种请求方式的请求
☀️@RequestMapping注解的params属性
params属性通过请求的请求参数匹配请求映射
get请求:内容放在请求头
post请求:内容放在请求体,更安全
2. @Controller和@Restcontroller
@RestController这个注解相当于 = @ResponseBody + @Controller一起作用。
当我们使用的时候 一个比较直观的感受 如果使用@RestController是将一些json数据返回给前端,
而@Controller则是返回视图页面。
这就是因为ResponseBody注解将Controller的方法返回的对象,通过适当的HttpMessageConverter
转换为指定格式后,写入到Response对象的body数据区。这个过程跳过正常的模型/视图流程中视图解析的过程。
3. @Component 和 @Bean(注入Bean)
@Component和@Bean的目的是一样的,都是注册bean到Spring容器中。
@Component 和 它的子类型(@Controller, @Service and @Repository)注释在类上。通过类路径扫描自
动检测并注入到Spring容器中。
@Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。
4. @Autowire 和 @Resource(装配Bean)
@Autowire 和 @Resource都可以用来装配bean,都可以用于字段或setter方法。
@Autowire 默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的
required 属性为 false。
@Resource 默认按名称装配,当找不到与名称匹配的 bean 时才按照类型进行装配。名称可以通过 name 属性
指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名,当注解写在 setter 方法上时,默认
取属性名进行装配。