Spring框架中的单例bean是线程安全的吗?
@Service
@Scope("singleton")
public class UserServicelmpl implements UserService {
singleton : bean在每个Spring lOC容器中只有一个实例。
prototype: 一个bean的定义可以有多个实例。
不是线程安全的
Spring框架中有一个@Scope注解,默认的值就是singleton,单例的。
因为一般在spring的bean中都是注入无状态的对象,没有线程安全问题,如果在bean中定义了可修改的成员变量,是要考虑线程安全问题的,可以使用多例或者加锁来解决。
什么是AOP,你们项目中有没有使用到AOP?
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑
抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
常见的AOP使用场景:
1.记录操作日志
2.缓存处理
3.Spring中内置的事务处理
记录操作日志思路:
**Spring中的事务是如何实现的?
其本质是通过AOP功能,对方法前后进行拦截,在执行方法之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
Spring支持编程式事务管理和声明式事务管理两种方式。
1.编程式事务控制: 需使用Transaction Template来进行实现,对业务代码有侵入性,项目中很少使用。
2.声明式事务管理: 声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
Spring中事务失效的场景有哪些
情况一:异常捕获处理
情况二:抛出检查异常
情况三:非public方法导致的事务失效
Spring的bean的生命周期
BeanDefinition
Spring容器在进行实例化时,会将xml配置的< bean >的信息封装成一个BeanDefinition对象,Spring根据BeanDefinition来创建Bean对象,里面有很多的属性用来描述Bean
1.通过BeanDefinition获取bean的定义信息
2.调用构造函数实例化bean
3.bean的依赖注入
4.处理Aware接口(BeanNameAware、BeanFactoryAware、ApplicationContextAware)
5.Bean的后置处理器BeanPostProcessor-前置
6.初始化方法(InitializingBean、init-method)
7.Bean的后置处理器BeanPostProcessor-后置
8.销毁bean
Spring的bean的循环引用
Spring的循环依赖:
三级缓存解决循环依赖(循环引用)
Spring解决循环依赖是通过三级缓存,对应的三级缓存如下所示:
//单实例对象注册器
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
private static final int SUPPRESSED_EXCEPTIONS_LIMIT= 100;
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256); //一级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16); //三级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16); //二级缓存
一级缓存作用:限制bean在beanFactory中只存一份,即实现singleton scope,解决不了循环依赖
如果要想打破循环依赖,就需要一个中间人的参与,这个中间人就是二级缓存。(一级缓存+二级缓存:但是不能解决代理对象)
三级缓存+二级缓存+一级缓存 解决代理对象的循环引用
三级缓存能解决初始化过程中的循环依赖,但是不能解决构造函数产生的循环依赖
构造方法出现了循环依赖的解决方法:(加注解)
public A(@Lazy B b){
System.out.println("A的构造方法执行了...");
this.b = b ;
}
SpringMVC的执行流程
1.用户发送出请求到前端控制器DispatcherServlet
2.DispatcherServlet收到请求调用HandlerMapping (处理器映射器)
3.HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给 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进行渲染视图(即将模型数据填充至视图中)
1.用户发送出请求到前端控制器DispatcherServlet
2.DispatcherServlet收到请求调用HandlerMapping (处理器映射器)
3.HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给4.DispatcherServlet。
5.DispatcherServlet调用HandlerAdapter (处理器适配器)
6.HandlerAdapter经过适配调用具体的处理器(Handler/Controller)方法上添加了@ResponseBody
7.通过HttpMessageConverter来返回结果转换为JSON并响应
Springboot自动配置原理
1,在Spring Boot项目中的引导类上有一个注解**@SpringBootApplication**,这个注解是对三个注解进行了封装,分别是:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
2.其中**@EnableAutoConfiguration是实现自动化配置的核心注解。该注解通过@lmport注解导入对应的配置选择器。
内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。在这些配置类中所定义的Bean会根据条件注解所指定的条件**来决定是否需要将其导入到Spring容器中。
3,条件判断会有像 @ConditionalOnClass 这样的注解,判断是否有对应的class文件,如果有则加载该类把这个配置类的所有的Bean放入spring容器中使用。
Spring框架常见注解(Spring、Springboot、Springmvc)
Spring的常见注解
SpringMVC常见的注解
Springboot常见注解