ssm和springboot

news/2025/1/7 18:49:30/文章来源:https://www.cnblogs.com/zyzyzyBlog/p/18655293

Spring

框架 = 原生API打成jar包+配置文件

Spring特点
AOP面向切面编程, TX声明式事务管理, Spring MVC提供了面向Web应用程序的集成功能。
Core Container 核心容器,在 Spring 环境下使用任何功能都必须基于 IOC 容器。DI。

Spring框架中的单例bean是线程安全的吗?
单例bean中定义了可修改(没用final修饰)的成员属性,且成员方法里有修改它的操作,就线程不安全。因为容器会给每一个请求分配一个线程,多线程并发执行该成员方法。(在bean上加@Scope注解,参数改为prototype把bean变成多例或加锁解决。)
一般不给bean设置可修改的成员属性(比如Service类和DAO类)

什么是IOC、DI
IOC是控制反转,把创建对象的任务交给Spring的BeanFactory,Spring通过包扫描将bean封装成BeanDefinition,然后存放到BeanDefinitionMap,需要的对象从这个map拿出BeanDefinition通过反射创建bean对象放入IOC容器并返回。依赖注入(DI)是IOC容器会将对象依赖的对象动态注入。

什么是AOP
AOP就是面向切面编程,拆分公共逻辑和业务逻辑,减少代码耦合,增加代码复用性。靠cglib动态代理和jdk动态代理实现,cglib动态代理是生成一个代理子类重写父类方法,jdk的动态代理是基于接口实现的。AOP常用场景有日志处理,事务处理,限流处理。包括切面、切点、通知、连接点。

项目中有没有使用到AOP
自定义登陆校验注解,标明注解可以用于方法、注解在运行时保留。并定义了切面类,其中的校验方法是对controller包下加了登陆校验注解的方法进行环绕通知,通 知内容是从请求头取出token为key,去redis中找对应的用户id。
用aop来记录了系统的操作日志,主要思路是,使用aop中的环绕通知+切点表达式,这个表达式就是某些包下要记录日志的方法,然后通过环绕通知的参数获取方法 的参数,比如类信息、方法信息、注解、请求方式等,获取到这些参数以后,保存到数据库。

Spring中的事务是如何实现的
分编程式事务和声明式事务,编程式事务用TransactionTemplate实现,跟业务代码耦合,很少用
声明式事用aop动态代理完成的,拦截方法的前后,在执行方法前开启事务,根据方法的执行结果选择提交或回滚(比如目标方法向上抛非检查异常就回滚没抛提交)。

Spring中事务失效的场景有哪些
事务失效是没保证原子性(没有全部成功或全部失败)
第一个,方法内捕获处理了异常,但没有抛出,事务通知接收不到目标抛出的异常就不回滚,解决方法是处理完了抛出去。
第二个,方法抛的不是运行时异常而是编译时异常或发生error,@Transactional中设置rollbackFor属性为Exception,这样通知捕 获到所有异常都会回滚事务。
第3个,非public方法。Spring 只给public方法创建代理、添加事务通知。
第4个,同一个类里非事务方法调事务方法。(用类的proxy对象调)。
同一个类里事务方法调事务方法,非代理对象则被调方法不能新开启事务
事务是通过AOP动态代理卖损束不提供接口,或者不通过第三方代理类调用,事务也会失效
上都是通过反射
三个传播机制。

bean的生命周期
spring扫描xml配置文件或加了bean注解的类并封装成BeanDefinition。根据它里的信息调构造函数实例化bean,接下来给bean依赖注入。如果实现了aware接口执行重写的set方法 。然后如果bean实现了后置处理器BeanPostProcessor,就会执行重写的before方法。接下来是执行初始化方法初始化Bean。然后是执行后置处理器BeanPostProcessor的重写的after方法,最后一步是容器关闭时销毁bean,如果定义了@preDestroy的方法会在此前执行。曾支付通知配置类实现过ApplicationContextAware接口,初始化时,在重写set的方法里给rabbitTemplate这个Bean设置投递失败时的回调函数(为记录日志和将消息再添加到消息表。)
接下来都是给bean初始化赋值。
BeanDefinition里面封装了bean的所有信息,比如,类的全路径,是否是延迟加载,是否是单例等信息
依赖注入,比如set方法注入,像平时用的@Autowire都是这一步完成
初始化方法,如实现了接口InitializingBean就要执行重写的方法,如自定义了初始化方法 添加了init-method标签或@PostContruct就要执行初始化方法
after方法,方法内用代理对象完成对bean增强。像AOP

Spring中的循环依赖

对象a初始化的时候注入了对象b,对象b在初始化时又注入了a。spring框架的三级缓存能解决非构造器注入的循环依赖,
①一级缓存就单例池,放初始化完的bean对象
②二级缓存:放没初始化的半成品bean
③三级缓存:缓存的是ObjectFactory,表示对象工厂,用来创建原对象或代理对象

循环依赖具体解决流程清楚吗?

首先就是执行a的构造函数,就有了半成品a对象,将这个半成品放入二级缓存,然后a对象该初始化了发现需要注入b对象,于是创建b对象,将半成品b存入二级缓存。然后b对象该初始化了,需要注入a对象,就从二级缓存获取a的半成品。b初始化完,Spring将b存入一级缓存并删除二级缓存中的b,然后将b注入给a,a初始化成功存入一级缓存并删除二级缓存的a。
但当a需要注入b的代理对象时,就要三级缓存来处理aop,三级缓存放的是对象工厂,B实例化后创建ObjectFactory对象存入三级缓存singletonFactories,用B的对象工厂创建动态代理类,最后对应的一级缓存存放的也是b代理对象。
三级缓存解决初始化中的循环依赖。但在构造方法中就出现了循环依赖,用@Lazy注解进行懒加载,需要对象时在创建
第一,先实例化A对象,同时创建ObjectFactory对象存入三级缓存singletonFactories  
第二,A在初始化的时候需要B对象,这时走B的生命周期
第三,B实例化完成,也会创建ObjectFactory对象存入三级缓存singletonFactories  
第四,B需要注入A,从三级缓存中获取ObjectFactory对象来生成一个A的对象同时存入二级缓存,这个是有两种情况,一个是可能是A的普通对象,另外一个是A的代			理对象,都可以让ObjectFactory对象来生产对应的对象,这也是三级缓存的关键
第五,B通过从二级缓存earlySingletonObjects 取出A的对象然后注入,B创建成功,存入一级缓存singletonObjects  
第六,回到A对象初始化,因为B对象已经创建完成,则可以直接注入B,A创建成功存入一次缓存singletonObjects 
第七,二级缓存中的临时对象A清除 

===========================================================================================

springMVC

1、什么是springMVC
Spring框架的一部分,springMVC是模型视图控制器,本质还是servlet,用于接收前台传递的参数并将处理后的数据返回给前端
SpringMVC为了解耦把工程结构分为三层,Modle层(数据访问层)、Cotroller层(处理用户发送 的请求)、View 层(页面显示层),其中Modle层分为两层:dao层、service层)

SpringMVC的执行流程知道嘛
在前后端分离的项目中,浏览器发起请求,DispatcherServlet(前端控制器)接收请求后,把请求的 URL给HandlerMapping(处理器映射器),它返回对应的一个处理器链(链是因为可能设置了一些拦截器)给DispatcherServlet。DispatcherServlet再调用对应的处理器适配器HandlerAdaptor,处理器适配器先处理入参数,然后执行处理器方法。处理器方法一般加了@Response注解,会把返回结果转换为JSON并原路返回给DispatcherServlet。DispatcherServlet 返回响应给前端。
在前后端不分离的项目中,不同的是处理器返回的是ModelAndView(逻辑视图)对象给DispatcherServlet,DispatcherServlet交给视图解析器解析成一个view对象也就是真视图,最后DispatcherServlet把模型数据填充到真视图中响应给前端。

{02CFCDFF-47A5-4FCA-84B9-34DD635517AE}扩展

1、用户发请求到前端控制器DispatcherServlet也叫调度中心
2、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
3、HandlerMapping找到具体处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),返回给DispatcherServlet。

4、DispatcherServlet调用HandlerAdapter(处理器适配器)。
5、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
现在的开发,基本都是前后端分离的开发的,并没有视图这些,一般加了@Response,handler直接通过HttpMessageConverter把返回结果转换为JSON并响应

6、Controller执行完成返回ModelAndView对象。
7、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
8、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
9、ViewReslover解析后返回具体View(视图)。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户

3.springMVC的工作原理
spring中的Dispacherservlet会拦截满足规矩的请求,截取URL中最后一串代码到配置中寻找是否有满足的映射,如果有的话会寻找映射对应的类,并且执行类的代码,将代码中需要传送跳转的请求封装到modelandview中并且返回,将modelandview中视图的url进行前缀或后缀的装配后进行页面和数据的渲染后将页面返回给用户看

3.springMVC优点:
本质是servlet,但少很多代码,有利于系统的维护和扩展。

Mybatis

Mybatis的缓存

mybatis的一级缓存和二级缓存都是基于本地缓存的,PerpetualCache,本质是一个hashmap,然后一级缓存的作用域是session级别的,默认打开,当session刷新或关闭之后缓存会消失。二级缓存是基于mapper和namespace的默认关闭,不受会话的影响,需要在配置文件中打开。二级缓存的数据需要实现Serializable接口。

Mybatis是否支持延迟加载?
延迟加载:就是在需要用到数据时才进行加载,比如用户类里有一个属性是订单集合,查用户时,如果用不到订单集合就设置延迟加载,加快查询速度,等用到这个订单时再去数据库查。并且Mybatis支持一对一关联对象和一对多关联集合对象的延迟加载。
因为Mybatis延迟加载默认关闭,在Mybatis配置文件中配置lazyLoadingEnabled=true,启用延迟加载。

Mybatis的一级、二级缓存用过吗?
一级缓存和二级缓存都是基于本地缓存的,采用PerpetualCache(本质是一个hashmap)存储,然后一级缓存默认是打开的,作用域是SqlSession,SqlSession如果刷新或关闭一级缓存就会消失。二级缓存默认关闭,作用域是SqlSessionFactory(mapper和namespace),可以在配置文件中打开。实体类想进二级缓存必须实现Serializable接口。

什么时候缓存失效(Mybatis的一,二级缓存清理缓存中的数据)
两次执行相同的sql查询语句间执行了任意的增删改,会让一、二级缓存都失效。

缓存查询顺序和写入
先查2后查1。SqlSession关闭之后,一级缓存中的数据会写入二级缓存。

service方法内执行两次同样的mapper方法会使用到缓存,service方法结束,缓存会被清

啥是动态SQL,Mybatis的常用的6个标签及作用

动态SQL是在程序运行时根据入参生成不同的sql
常用的标签:
<if> : 进行条件的判断
<where>:在<if>判断后的SQL语句前面添加WHERE关键字,并处理SQL语句开始位置的AND 或者OR的问题
<foreach>:遍历操作
<trim>:可以在SQL语句前后添加或者去掉指定字符
<set>:  主要用于修改操作时出现的逗号问题
<choose> <when> <otherwise>:类似switch-case语句.在所有的条件中选择其一<select id="selectUsers" parameterType="map" resultType="com.example.entity.User">SELECT * FROM user<where><if test="name != null and name != ''">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="age != null">AND age = #{age}</if><if test="addressList != null and addressList.size() > 0">AND address IN<foreach item="address" index="index" collection="addressList" open="(" separator="," close=")">#{address}</foreach></if></where></select><update id="updateUser" parameterType="com.example.entity.User">UPDATE user<set><if test="name != null and name != ''">name = #{name},</if><if test="email != null and email != ''">email = #{email},</if><if test="age != null">age = #{age},</if><if test="address != null and address != ''">address = #{address}</if></set>WHERE id = #{id}</update><select id="selectUserByConditions" parameterType="map" resultType="com.example.entity.User">SELECT * FROM user<where><choose><when test="name != null and name != ''">AND name LIKE CONCAT('%', #{name}, '%')</when><when test="email != null and email != ''">AND email = #{email}</when><otherwise>AND age = #{age}</otherwise></choose></where></select></mapper>

MyBatis如何获取自动生成的(主)键值
给insert标签中useGeneratedKeys属性值设为true,keyProperty 属性值设为自增键对应的实体类中属性。

示例:
<insert id="insertname" useGeneratedkeys="true" keyProperty="id">insert into names (name) values (#{name}) 
</insert>

Mybatis 如何完成MySQL的批量操作
标签遍历集合来拼装SQL语句,#{}里存字段的值

例如:
<insert id="insertBatch" >insert into tbl_employee(last_name,email,gender,d_id) values <foreach  collection="emps" item="curr_emp" separator="," >(#{curr_emp.lastName},#{curr_emp.email},#{curr_emp.gender},#{curr_emp.dept.id}) </foreach>
</insert>

4.什么情况下必须用${}

当入参不能用“”包起来的时候,比如入参是表名(动态拼接表名的时候)或入参是order by排序语句中的字段名。因为#{}会给入参加“”把它变成字符串,不合sql语法。

1.statement和preparestatement的区别
Statement用于执行静态sql语句,在执行时,必须指定一个事先准备好的sql语句。
可能会引起sql注入,就是用户输入的参数里面有可能包含了一些sql关键词比如 “or,where”等,有可能会改变sql语句的逻辑
PrepareStatement是预编译的sql语句对象,sql语句被预编译并保存在对象中,在执行时可以为“?”动态设置参数值。
preparestatement 通过占位符的形式,传入的参数会被“”包裹起 从而避免了sql注入。

返回结果的字段对应实体类字段有就写入,没有不写入。#{}自动加‘’不合sql语法,in、表名得用${},模糊like #{}得变形${}可。
分步查询的优点:核心配置文件中开了延迟加载,没取第二步结果就不执行第二步(少一次查询),association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)|eager(立即加载)。

2.where :
当where标签中有内容时,会自动生成wvhere关键字,并且将内容前多余的and或or去掉
当where标签中没有内容时,此时where标签没有任何效果
注意: where标签不能将其中内容后面多余的and或or去

mats默认开启一级缓存,“作用域是同一个sq1Session,相同结果从缓存拿,不访问数据库。

<select id="orderFHDetail" parameterType="com.ai.warehouse.order.entity.OrderRecord" 	      resultType="com.ai.warehouse.etl.dao.bean.OrderDetailStatisBean">	SELECT * 	FROM    order_record ur	<where><if test="crttime != null">and <![CDATA[ ur.crtTime     >=   #{crttime}]]></if><if test="crttimeEnd != null">and <![CDATA[ ur.crtTime     <=   #{crttimeEnd}]]></if><if test="ordertype != null and ordertype!= '' ">and ur.orderType = #{ordertype,jdbcType=VARCHAR}</if><if test="partnername != null">and ur.partnerName = #{partnername,jdbcType=VARCHAR}</if></where>
</select>

低频

什么是Mybatis一个基于xm文件的持久层框架,它封装了JDBC,开发时只需要关注SQL语句,不用手动加载驱动,创建和释放连接。它通过标签把SQL中的动态参数进行映射生成最终的SQL语句,然后把结果映射转为Java对象返回。Mybatis的优点mybatis把所有sq语句都封装起来,把sql语句和代码分开,方便去维护和拓展,它的映射标签,把对象和数据库表的字段映射起来,也可以使用where if 等标签来编写动态的sql。Mybatis延迟加载的底层原理知道吗?首先用cglib创建user对象的代理对象,当调用user对象的getOrderList()方法,然后判断返回值是否为空,为空就调目标对象的setOrderList()方法(去数据库里查数据并存到user对象的订单集合属性中,最终获取结果。	延迟加载在底层主要使用的CGLIB动态代理完成的第一是,使用CGLIB创建目标对象的代理对象,这里的目标对象就是开启了延迟加载的mapper第二个是当调用目标方法时,进入拦截器invoke方法,发现目标方法是null值,再执行sql查询第三个是获取数据以后,调用set方法设置属性值,再继续查询目标方法,就有值了MyBatis执行流程首先读取mybatis的配置文件(mybatis-config.xml),加载运行环境和映射文件。然后构建会话工厂SqlSessionFactory,然后使用会话工厂创建会话对象SqlSession,通过 SqlSession 获取 Mapper 接口代理对象。调用 Mapper 接口的方法时用 Executor执行器执行映射的SQL 语句,并对结果进行映射,同时Executor执行器负责维护缓存 。Executor执行器里有一个MappedStatement类型的参数,封装了Mapper 接口方法的信息,包括输入参数映射,输出结果映射。②构造会话工厂SqlSessionFactory,一个项目只需要一个,单例的,由spring进行管理③会话工厂创建SqlSession对象,这里面就含了执行SQL语句的所有方法。Mapper 接口定义了与数据库操作相关的方法。④操作数据库的接口,Executor执行器,同时负责查询缓存的维护⑤Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息⑥输入参数映射⑦输出结果映射

=====自己笔记=
1.statement和preparestatement的区别
Statement用于执行静态sql语句,在执行时,必须指定一个事先准备好的sql语句。
可能会引起sql注入,就是用户输入的参数如果包含sql的关键词比如 “or,where”等,有可能会改变sql语句的逻辑
PrepareStatement是预编译的sql语句对象,sql语句被预编译并保存在对象中,在执行时可以为“?”动态设置参数值。
preparestatement 通过占位符的形式,传入的参数会被“”包裹起 从而避免了sql注入。

返回结果的字段对应实体类字段有就写入,没有不写入。#{}自动加‘’不合sql语法,in、表名得用${},模糊like #{}得变形${}可。
分步查询的优点:核心配置文件中开了延迟加载,没取第二步结果就不执行第二步(少一次查询),association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)eager(立即加载)。

2.where :
当where标签中有内容时,会自动生成wvhere关键字,并且将内容前多余的and或or去掉
当where标签中没有内容时,此时where标签没有任何效果
注意: where标签不能将其中内容后面多余的and或or去

mats默认开启一级缓存,“作用域是同一个sq1Session,相同结果从缓存拿,不访问数据库。

Mybatisplus

Wrapper做where条件。
set值非常量时,用updatelamdaWrapper的setSql()。

简单Iservice 增:有id为改 删remove 查:一个get,批量list,数量count。 有where的查/改 :lamda
复杂
where,在mapper定义,service调baseMapper(泛型,就是本mapper)和lamdawrapper.
涉及别的表,注入别的Mapper。

MP的批量新增,基于预编译的批处理,性能不错
配置jdbc参数,开rewriteBatchedStatements,性能最好

分页:封装统一的分页查询dto存分页参数让dto继承,和返回dto
get请求的参数是可以直接用对象接收的,定义多个参数用@rewuestParam

Springboot

配置繁琐,引依赖繁琐,
自动配置,提供起步依赖,
创建web应用 创建maven工程,手动添加依赖,写个第三方bean的配置类加@Configuration@ComponentScan("comitheima.controller")@EnableWebMvc

创建web应用,创建SpringIntialzer工程(继承SpringBootStart),勾选功能自动添加web的SpringWeb起步依赖。通过启动类自动配置。

Springboot特点
简化Spring应用开发,内嵌tomcat服务器打成jar包可直接运行,提供起步依赖Starter,实现一个功能不用考虑导哪些jar包和两个功能引的相同jar包版本冲突,不用写配置类。

Springboot自动配置原理
Spring Boot项目引导类上的@SpringBootApplication 注解能启用自动配置,它封装了@EnableAutoConfiguration注解,是实现自动配置的核心,这个注解又用@import注解导入对应的配置选择器,配置选择器会读取该项目和该项目导入依赖Jar包的classpath路径下META-INF/spring.factories文件中所有配置类的全类名,这些配置类根据条件把定义的bean配置到Spring容器中。配置属性通过 application.properties 或 application.yml 实现,简化Spring 应用的配置。

用Spring Boot项目引导类上的注解@SpringBootApplication,它封装了三个注解@SpringBootConfiguration表示当前类是配置类,@ComponentScan 用来扫	描包下的bean加入spring容器。
@EnableAutoConfiguration,该注解通过`@Import`注解导入对应的配置选择器。配置选择器会读取该项目和该项目导入依赖Jar包的classpath路径下META-	INF/spring.factories文件中所有配置类的全类名。这些配置类会根据条件注解里的条件决定是否把定义的bean导入到Spring容器中。
条件比如判断是否有对应的class文件(引入了起步依赖),如果有则加载该类,把配置类中所有Bean放入spring容器。

SpringBoot配置文件有哪些 怎么实现多环境配置 难度系数:⭐
Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
application 配置文件用于 Spring Boot 项目的自动配置。
bootstrap配置文件的特性:
bootstrap 由父 ApplicationContext 加载,比 applicaton 优先加载
bootstrap 里面的属性不能被覆盖
bootstrap 配置文件有以下几个应用场景:

使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
一些固定的不能被覆盖的属性;
一些加密/解密的场景;
提供多套配置文件,如:

applcation.properties
application-dev.properties
application-test.properties
application-prod.properties

运行时指定具体的配置文件

Spring 的常见注解有哪些?

声明类为bean:@Controller、@Service、@Repository、           @Component
依赖注入相关的:@Autowired、@Qualifier、     @Resourse
设置作用域 :@Scope
spring配置bean相关的:  @Configuration,@ComponentScan 和 @Bean (方法上)
aop相关做增强的 : @Aspect,@Before,@After,@Around,@Pointcut

SpringMVC常见的注解有哪些?想request开头

@RequestMapping:映射请求路径;(类上)
@PostMapping、@GetMapping这些。(方法上)
@RequestParam:指定请求参数的名称;
@PathViriable:从请求路径下中获取请求参数(/user/{id}),传递给方法的形式参数;
@RequestBody:把http请求的json数据,转为java对象。把方法返回对象转化为json对象;(方法参数前)
@RequestHeader:获取指定的请求头数据,

Springboot常见注解有哪些?想Spring Boot开头

Spring Boot的核心注解是@SpringBootApplication , 他由几个注解组成 :

  • @SpringBootConfiguration: 组合了- @Configuration注解,实现配置文件的功能;
  • @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项
  • @ComponentScan:Spring组件扫描
    =======================================SpringBoot笔记
    不同后缀配置文件 优先级 application.properties>yml>yaml

变成绿色配置文件 facet 绿炮 +号

读取() :属性上加@value("${}")。自定义一个类上加@ConfigurationProperties(prefix = "xx.xxx.xxx"),类属性自动对应,再引入一个依赖。注入Environment,用他的 get() 方法。

多环境启动配置:1、yaml文件内用---分割多个环境(每个环境用profile键设置dev、pro)的配置,打active补全,启用哪个,用。2、pro文件是建立一个环境一个pro 文件,

不同位置的同名配置文件优先级:jar包所在target目录里/文件系统(config里>外)> idea里resource文件里/类路径里 (config里>外) 。自己用外层,上线用内层, 被打回来修bug删内层用外层。上线时临时要修改配置把内层的粘到jar包所在target目录里进行修改。打包后用文件系统的。开发用类 路径里,(2.5 和2.4.6target目录里还得加个目录)

boot整合junit后的测试步骤
boot引webstarter 自动加junit测试功能
1、test目录下测试类所在包,对应到 源码目录/java目录 下要包含要测试的bean。不在的话@bootTest里加classes = 启动类.class。2、测试类加@bootTest, @autowire注入自己开发的bean,写个测试方法加@test测试bean的方法。

Spring 框架是多模块的集合:
自己笔记==
Spring 创建Bean用它的无参构造(私有也能用反射调)。FactoryBean实现xx,内部是非静态的创建对象方法。
给Bean加autowire标签会自动依赖注入(装配)默认先用无参构造加反射注入(因为是无参)。再set方法注入且按名注入,Spring按serviceimplBean的set方法剥set首字母转小为id在容器找Bean。自动依赖注入(装配)优先级低于构造 注入,set() 注入。

Bean生命周期中可执行俩方法,

IoC :Spring 框架创建对象交给 IoC 容器管理,对象间的相互依赖交给 IoC 容器管理,由 IoC 容器完成对象的注入(只需要配置创建对象需要的元数据如 XML 文件、注解、 Java 配置类。)。容器是个 Map存放各种对象。Bean 是被 容器管理的对象

Bean生命周期
容器根据Bean的配置用 Java Reflection API 创建 Bean 的实例。

执行构造方法
用 set() 方法设置一些属性值。
如果实现了 *.Aware 接口,就调用相应的方法。(setBeanName,setBeanFactory,setApplicationContext)
如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
如果 Bean 实现了 InitializingBean 接口,执行 afterPropertiesSet() 方法。
如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法

Bean 作用域:
singleton (默认):容器中唯一。
prototype : 每次注入都创建新的 bean 实例。
request (仅 Web 应用可用): 每次 HTTP 请求产生一个新的 bean
session (仅 Web 应用可用) : 新 session 的第一个 HTTP 请求产生一个新的 bean(当前 HTTP session 内有效)
application/global-session (仅 Web 应用可用):每个 Web 应用一个 Bean(仅在当前应用启动时间内有效)
websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。

有状态单例 Bean 的线程安全问题:
Bean 中不定义可变的成员变量。
类中定义ThreadLocal 成员变量,将可变成员变量保存在 ThreadLocal 中。

AOP:把与业务无关,却所有业务模块都调用的逻辑(例如事务处理、日志管理、权限控制等)封装起来(基于动态代理,对象实现了接口, AOP 用 JDK Proxy创建代理对象。对象没有实现接口,用 Cglib 生成被代理对象的子类。)

连接点就是原来公共代码所在位置也就是可织入切面的位置,方法前后和抛异常之后的Catch块里
切点就是增强的方法,一个切点对应多个连接点
通知就是切点内的增强代码即公共代码,放在不同连接点叫前置环绕异常通知

目标(Target):被通知对象,所属类中所有方法均为连接点(JoinPoint),连接点中被切面拦截 / 增强的叫切入点(Pointcut),切入点中加的增强的代码叫通知(Advice)。
(Aspect)切入点(Pointcut)+通知(Advice)==切面。

代理(Proxy):向目标对象应用通知之后创建的代理对象
Weaving(织入):将通知应用到目标对象并生成代理对象的过程

切面太多的话,最好选择 AspectJ
AspectJ 的通知类型:Before(前置通知方法调用之前触发
After (后置通知):方法刚调用后触发
AfterReturning(返回通知):方法调用完成返回结果值之后触发
AfterThrowing(异常通知):方法抛出 / 触发异常后触发。
AfterReturning 和 AfterThrowing 两者互斥。
Around (环绕通知):任意的在目标对象的方法调用前后搞事,甚至不调用方法

多切面@Order小的先执行

DispatcherServlet拦截客户端(浏览器)发来的请求后根据请求信息调用HandlerMapping 。HandlerMapping 根据 URL 去匹配能处理的 Handler(也就是我们平常说的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装。DispatcherServlet 调用 HandlerAdapter适配器执行 Handler 。Handler 完成对用户请求的处理后,会返回一个 ModelAndView (包含了数据模型以及相应的视图)对象给DispatcherServlet。Model 是返回的数据对象,View 是个逻辑上的 View。ViewResolver 会根据逻辑 View 查找实际的 View。DispaterServlet 把返回的 Model 传给 View(视图渲染)。把 View 返回给请求者(浏览器)

统一异常处理怎么做?
用到 @ControllerAdvice + @ExceptionHandler 这两个注解 。给所有或指定 Controller 织入异常处理逻辑,当 Controller 中的方法抛出异常,ExceptionHandlerMethodResolver 中 getMappedMethod 方法决定异常被哪个@ExceptionHandler 注解修饰的方法处理异常。

Spring 管理事务:
编程式事务:在代码中硬编码(适用分布式系统) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,事务范围过大会提交超时,因此事务要比锁的粒度更小。
声明式事务:XML 配置文件中配置或基于注解(单体或简单业务) : 通过 AOP 实现(基于@Transactional )

可以很方便地对数据库进行访问、可以很方便地集成第三方组件(电子邮件,任务,调度,缓存等等)、对单元测试支持比较好、支持 RESTful Java 应用程序的开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/864962.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习 - Nginx - 浅谈反向代理正向代理

一张图搞懂反向代理&正向代理反向代理 客户端发送请求 连接到互联网以后,不能直接访问到业务服务器(如Tomcat集群),需要通过Nginx反向代理才能访问,同理Tomcat返回报文数据的时候也不能直接返回给客户端,也需要通过Nginx才可以 正向代理 用户通过代理服务器(网关)访…

2025年简单好用的电脑桌面便签记事本软件

在新的一年,很多打工人希望自己可以更加高效工作,把每件事管理的井井有条,实现升职加薪。 每天使用电脑办公,想要随手记录工作事项、零散琐事,用一款电脑桌面便签或记事本软件是非常方便的。 今天为大家推荐一款2025年简单又好用的电脑桌面便签记事本软件:敬业签! ~ 桌面…

基础知识-虚拟化(Virtualization)技术

(250106) 参考资料 KVM 虚拟化技术 | cnblogs | 惨绿少年@clsn.io 虚拟化介绍 | cnblogs | 休耕 云计算与虚拟化技术发展编年史 | cnblogs | 云物互联 nova系列二:kvm介绍 | cnblogs | linhaifeng 虚拟化与容器 | cnblogs | marility 《LPIC-3-Virtualization-and-Containe…

【k8s基础】k8s 基本使用

介绍及教程大全 Kubernetes中文文档 结构模型 k8s 是经典的一对多模型,有一个主要的管理节点master和许多的工作节点slaver。当然,k8s 也可以配置多个管理节点,拥有两个以上的管理节点被称为 高可用。k8s 包括了许多的组件,每个组件都是单运行在一个docker容器中,然后通过…

Scss 入门

Scss 是对 CSS 的扩展,提供了比 CSS 更简洁的语法和更强大的功能。不过,在部署时,我们要先把 Scss 编译成 CSS,才能让浏览器识别。编译 Scss 的方法有很多,这里我们使用 VS Code 的插件 Live Sass Compiler 进行自动编译。 基本准备配置保存目录。在 VS Code 配置文件中添…

Seed Lab实验:RSAPublic-Key Encryption and Signature Lab

Seed Lab实验:RSAPublic-Key Encryption and Signature Lab笔记RSAPublic-Key Encryption and Signature Lab 1.推导RSA私钥 import gmpy2p = 0xF7E75FDC469067FFDC4E847C51F452DF q = 0xE85CED54AF57E53E092113E62F436F4F e = 0x0D88C3n = q * p phi = (p - 1) * (q - 1) d =…

双稳态触发器

双稳态触发器双稳态触发器是一种具有记忆功能的逻辑单元电路,它能储存一位二进制码。 特点有两个稳定状态“0”态和“1”态; 能根据输入信号将触发器置成“0”或“1”态; 输入信号消失后,被置成的“0”或“1”态能保存下来,即具有记忆功能。RS触发器 基本RS触发器 输入低电…

在Lazarus下的Free Pascal编程教程——以数据处置推动程序运行的模块化程序设计方法

0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。 了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和…

foobar2000 v2.24.1 汉化版

foobar2000 v2.24.1 汉化版 -----------------------【软件截图】---------------------- -----------------------【软件介绍】---------------------- foobar2000 是一个 Windows 平台下的高级音频播放器.包含完全支持 unicode 及支持播放增益的高级标签功能. 特色: * 支持的…

ABB机器人IO板DSQC652维修方法归纳

ABB机械手IO板DSQC652维修需要一定的专业知识和技能,以下是详细的维修步骤和注意事项:1. 初步检查断电操作:在维修前,确保机器人系统完全断电,避免触电或损坏设备。外观检查:检查DSQC652板是否有明显的物理损坏,如烧焦痕迹、裂纹或元件脱落。连接检查:检查IO板与控制器…

车载以太网一致性测试套件TAE.AETP

随着汽车电子电气架构的发展,高带宽、高速率的数据通信需求逐步涌现,具有稳定、高效特点的车载以太网技术逐步成为汽车主干网通信主流方案。为了满足复杂的通信需求,越来越多的以太网通信协议被应用到车载领域与之而来的是更多新技术的测试验证需求,经纬恒润自主研发的车载…