1.IOC和AOP
IOC是控制反转,将创建对象的权利反转交给spring去管理,由spring框架统一管理项目中的对象,把由spring生成的对象称为bean对象,spring可以对对象进行功能上的增强
AOP是一种面向切面编程的思想,使用动态代理的方式,为目标对象提供代理对象,在不修改目标类的方法/代码基础上,为目标类添加额外的功能,将额外的功能横切到目标类中
2.IOC和DI
DI依赖注入 将对象依赖属性(简单值,集合,对象)通过配置设置给该对象
在IOC的基础上把对象注入到需要的地方
3.spring管理注入对象的方式
xml配置方式
属性注入,构造方式注入
注解方式
4.自动注入的注解
声明bean的注解
@RestController,@Service,@Repository,@Component
控制层,业务层,数据访问层,基本组件
Bean的生命周期属性
@Scope 设置类型 包括设置spring容器如何创建BEAN实例
Singleton 单例 一个spring容器中只有一个bean实例,默认模式
protetype 每次调用新建一个bean
request web 项目中,给每个http request新建一个bean
注入bean的注解
@Autowired:由spring提供
当有多个同一类型的bean时,可以用@Qualifier("name")来指定,与@Autowired配合使用
@Resourse:由java提供
5.spring 中bean和new的对象有什么区别
bean对象由spring创建,根据我们的配置(事务,日志,统一异常处理),可以进行功能上的增强
自己new的对象就是最原始的对象,没有任何增强
6.AOP有哪些术语,有哪些通知
连接点:类中可以被增强的方法
切入点:类中实际被增强的方法
通知:给切入点增加的功能
目标:被增强的类
代理:代理对象
前置通知:方法执行之前
后置通知:方法执行之后,无论有没有异常都执行
异常通知:方法出现异常执行
返回通知:方法执行之后,有异常不执行
环绕通知:可实现上述四个通知
7.AOP 的实现方式
xml配置方式
注解方式
8.事务管理,实现方式,原理
事务是数据库的特性,spring事务管理只是spring框架对事务开启提交回滚进行管理
编程式事务:需要自己在代码中提交回滚
声明式事务:在类或者方法上声明即可,使用@Transactional(rollbackFor=Exception.class)
使用动态代理对象
9.声明式事务哪些场景失效
1.@T被用在非public方法上
2.数据库事务未被开启或数据库引擎不支持事务,mysql只有innodb引擎支持事务
3.发生异常被捕获,认为方法没有异常
4.发生编译期异常
10.springweb(MVC)运行流程
用户发送请求到前端控制器DispatherServlet,收到请求后调用HandlerMapping处理器映射器找到具体的处理器(解析地址)查找xml配置或者注解配置,生成处理器对象及拦截器,然后返回控制器,经过处理器适配器调用具体的处理器,执行完成后向前端响应结果
11.Sevlet过滤器与spring的拦截器
过滤器属于servlet规范中定义的,拦截器是spring中定义的
过滤器可以拦截所有进入到java后端的请求,拦截器只能拦截进入到处理器(controller)web层的请求
12.spring和springboot
springboot是对spring的搭建配置进行简化,简化了搭建过程,没有替代,底层依旧使用spring,提高了开发效率
13*.spring常用注解
@Component:泛指各种组件
@Controller、@Service、@Repository都可以称为@Component。
@Controller:控制层
@Service:业务层
@Repository:数据访问层
@Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的,@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用。
@Configuration
声明当前类为配置类;
@Bean
注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式;
@ComponentScan
用于对Component进行扫描;
@Transactional
14*.Bean的生命周期
宏观上讲被分为5个阶段:
实例化-->属性赋值-->初始化(最关键的 根据我们各种注解配置,在这一步进行落地实现)-->被放入容器使用-->销毁
15*.bean是线程安全的嘛
bean有两个类型 单例和原型 如果是单例,始终只创建一个对象,所有请求共用同一个对象,那么对该单例对象中的成员变量也就只有一份,所有请求共用,所以单例bean使用时存在线程安全问题.
单例bean又分为有状态和无状态的
有状态:就是有成员变量,而且成员变量可以存储数据,就有可能多线程操作出现问题
无状态:注入的对象不用于存储数据,只是调方法,每一次请求中的参数数据都是相互隔离的,多线程安全
如果为原型bean,每次请求都会创建新的对象 ,它就不会存在线程安全问题
单例bean线程安全问题解决:如果成员变量是共享的,多线程操作时如++操作要进行加锁控制
如果每个请求中,都需要一个属于自己的成员变量:
1.把单例bean改为原型bean
2.使用ThreadLocal为每一次的请求提供变量副本
16*.bean的循环依赖
class A(){
B b;
}
class B(){
A a;
}
虽然A,B之间相互关联,但是创建对象时没有任何问题
但是在spring中,会存在循环依赖(spring已经解决了此问题)
在spring中如果使用@Autowired注解,那么在创建A对象时,需要为关联的b对象注入值,需要去创建对象b,创建对象B 时,需要为关联的a注入值,但是此时的a还没有创建完成,形成死循环.
spring如何解决循环依赖问题
spring中使用三级 缓存来解决这个循环依赖问题
三级缓存其实就是三个map对象,来存储不同的对象
一级缓存:singletonObjects一级缓存对象,主要存储创建,初始化完成的bean对象
二级缓存:earlySingletonObjects主要存储实例化完成但还未初始化完成的半成品对象
三级缓存:singletonFactories 主要存储来创建对象的工厂对象,创建a时,还有一个创建a的工厂对象
创建A时,需要用到B,A创建了一半,把它放到二级缓存中,把创建A的工厂放到三级缓存中,把半成品A注入到B中,B完成了创建,把B 放到了一级缓存中,把B注入到A中,对象完成了创建
17*.SpringBoot的自动装配原理
@SpringBootApplication,里面包含了三个注解标签
@ComponentScan 扫描启动类所在的包下的类
@SpringBootConfiguration
@EnableAutoConfiguration
@Import({AutoConfigurationImportSelector.class})
自动配置,根据pom.xml中的配置的相关依赖,进行选择性的加载,读取相关依赖的配置类
springBoot 启动时,首先对 application.yml 和 pom.xml 文件进行读取,获取到项目中使用到的第三方组件,然后读取 spring.factories 中的 spring 支持的配置类,最后加载项目中所使用到的组件配置类