ssm框架

将一个类声明为Bean的注解

  • @Component :通用的注解,可标注任意类为 Spring 组件。

  • @Respository :对应Dao层/Mapper层

  • @Service :对应业务层

  • @Controller :对应控制层

@AutoWired 与 @Resource的区别

  • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
  • Autowire 默认注入方式时byType, Resource默认注入方式是byName
  • 当一个接口存在多个实现类的情况下,@Autowired@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称
  • @Autowired 支持在构造函数、方法、字段和参数上使用。@Resource 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。

Bean的作用域

singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。

prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。

request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。

session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。

application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。

websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。

解决Bean的线程安全问题

  • 在Bean中尽量避免定义可变的成员变量
  • 在类中定义一个ThreadLocal成员变量,将可变的成员变量保存在ThreadLocal

Bean的生命周期

  1. 从beanDefinitioon中获取bean配置信息
  2. 执行构造函数,实例化bean
  3. 依赖注入:装载bean的属性
  4. 处理aware接口
  5. BeanPostProcessor-before前置处理
  6. 初始化方法,实现了接口InitializingBean或者自定义了方法init-method
  7. BeanPostProcessor-after后置处理
  1. 启动容器:加载Bean
  2. 实例化Bean对象
  3. 依赖注⼊:装配Bean的属性
  4. 初始化Bean:执⾏aware接⼝⽅法、预初始化⽅法、初始化⽅法、后初始化⽅法
  5. 关闭容器:销毁Bean

IOC

IOC是指控制反转,Java开发中对象的创建和管理交给IOC容器,需要哪个对象,直接从容器里面去取,不需要手动new一个对象。

最常见的实现方式为依赖注入(DI)

Spring AOP

AOP是指面向切面编程,是将那些公共的逻辑或责任从业务代码中封装起来,形成一个个切面以减少重复代码,降低耦合度,通过动态代理实现

Spring事务的实现原理

  • Spring事务的实现方式有两种:编程式事务和声明式事务。编程式事务是用户自己通过代码来控制事务,而声明式事务则是通过@Transaction注解来实现
  • Spring事务是基于数据库事务和AOP机制实现的,是AOP的一个核心体现,当一个方法添加@Transaction注解后,spring会基于这个类生成一个代理对象,将这个代理对象作为bean,当使用这个代理对象的方法时,若有事务处理,会先关闭事务的自动提交,然后去执行具体的业务逻辑,执行过程中没有异常,则代理逻辑会直接提交,若出现异常,则会根据需要去进行回滚操作。
  • Spring事务的隔离级别对应数据库的隔离级别。
  • Spring事务的传播机制是基于数据库来做的,一个数据库连接一个事务,若传播机制要新开一个事务,实际上就是先建立一个数据库连接,然后执行sql语句。

事务失效的情况

spring事务的原理是AOP,进行了切面增强,失效的根本原因是这个AOP不起作用了。

  • 数据库不支持事务
  • 方法不是public的,@Transactional只能用在public的方法上。
  • 没有被spring管理
  • 发生自调用,类里面使用this调用本类的方法(this通常省略),此时这个this对象不是代理类,而是userService本身。
  • 异常被捕获

循环依赖

循环依赖:两个或两个以上的bean互相持有对方,最终形成闭环。

一级缓存+二级缓存解决普通对象的循环依赖

  • 一级缓存:单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象

  • 二级缓存:缓存早期的bean对象,尚未装配属性(生命周期还没走完)

  • 三级缓存:缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的

Spring里面的设计模式

  • 单例模式:Spring里面的Bean都是单例的,容器里只有一个bean实例
  • 工厂设计模式 :BeanFactory、ApplicationContext创建对象
  • 代理模式:AOP功能的实现
  • 模板方法模式:jdbcTemplate操作数据库
  • 适配器模式:AOP的增强或通知

SpringMVC执行流程

1、用户发送出请求到前端控制器DispatcherServlet,这是一个调度中心

2、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。

3、HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。

4、DispatcherServlet调用HandlerAdapter(处理器适配器)。

5、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。

6、Controller执行完成返回ModelAndView对象。

7、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。

8、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。

9、ViewReslover解析后返回具体View(视图)。

10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

11、DispatcherServlet响应用户。

前后端分离,没有视图这些,一般都是handler中使用Response直接结果返回

SpringBoot自动配置原理

  • 在SpringBoot项目的启动类上有一个注解@SpringBootApplication,它对@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解进行了封装。

  • @EnableAutoConfiguration是实现自动配置的核心注解,它内部就是读取项目对应的jar包的classpath下的spring.factories文件中的所配置的类的全类名。在这些配置类中所定义的bean会根据条件注解@ConditionalOnxx所指定的条件来决定是否将其导入到容器中;

  • 条件判断会有@ConditionalOnClass这样的注解,判断是否有对应的class文件,有则加载该类,把这个配置类的bean放入容器。

Mybatis执行流程

  1. 读取mybatis-xml配置文件
  2. 构建会话工厂SqlSessionFactory,一个项目只要一个,由spring进行管理
  3. SqlSessionFactory创建SqlSession对象,包含执行sql语句的所有方法
  4. 操作数据库的接口,Executor执行器,动态生成SQL语句,同时负责查询缓存的维护
  5. Executor接口的执行方法中有一个MapperStatement类型的参数,封装了映射信息
  6. 输入参数映射
  7. 封装结果集

Mybatis的延迟加载

延迟加载:需要用到数据时才进行加载,不需要数据时就不加载

在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false,默认是关闭的

延迟加载在底层主要使用的CGLIB动态代理完成的

第一是,使用CGLIB创建目标对象的代理对象,这里的目标对象就是开启了延迟加载的mapper

第二个是当调用目标方法时,进入拦截器invoke方法,发现目标方法是null值,再执行sql查询

第三个是获取数据以后,调用set方法设置属性值,再继续查询目标方法,就有值了

Mybatis的一级缓存和二级缓存

  • 一级缓存又叫本地缓存,其存储作用域为 Session,当Session进行flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存
  • 二级缓存是基于namespace和mapper的作用域起作用的,不依赖于sqlSession,在映射XML文件配置<cache></cache>,实现了sqlSession对象中数据的共享。

一级缓存是为了避免每次查询都去数据库中找,后续的sql在命中缓存的情况下直接去本地缓存读取,sqlSession级别。
二级缓存是跨sqlsession的,存在脏读问题,默认关闭

MyBatis查询的先后顺序:
二级缓存->一级缓存->数据库

#{}${}的区别

  • #{}会进行预编译处理,可以防止SQL注入,${}没有预编译处理,直接拼接字符串,存在SQL注入问题,不安全。
  • 在进行预编译处理时,#{变量}会替换为?,同时对变量进行数据类型检测,若为字符类型,会自动加上‘’

sql 注入是将用户输入的数据拼接到代码中,并被当成 sql 语句执行。
如:
s=“ ” +“1 or 1=1”;
select * from user where id=‘%s’;
拼接后为:select * from user where id=’ ’ or 1=1;
可以通过该SQL恶意去获取user表里的所有信息,不安全

一般来说,更建议用#{},但是在一些变量为字段名、表名的情况下,则用${}(因为#{}会自动加引号,导致错误)

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

容与0801

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值