文章目录
spring 高频问题
1.spring/springboot/springmvc的区别
- spring是使用DI,ioc来管理javabean,使用aop解耦组件的容器框架,
- spring mvc是用一个使用spring来管理web应用的框架, 提供了分离式的方法来开发web应用
- spring boot做了一下对springbean的默认配置,极大了简化了开发,自动配置,起步依赖,各种starter
- spring cloud 构建于spring boot之上,符合springboot的特性,云应用开发工具,关注与全局的服务治理框架,包括 apigateway网关,eurake注册中心,configserver配置中心,hystrix熔断器等等.
- spring cloud data基于spring stream.微服务数据流
2.什么是自动配置
- 作为开发者,不用担心具体的依赖项和他们的兼容版本,spring都在各个starter中配置好了,在开发各种应用的时候只需要引入对应的starter就行,比如
3.什么是spring boot starter
- 启动器是一套方便的依赖描述符,将它放在程序中就可以一站式获取你所需要的所有的spring的组件,
4.spring中处理两个相同名称的bean
两个同样名称的bean,直接使用@Autowired
会出现异常,
此时需要配合使用另外一个注解@Qualifier
@service("u")
UserService.java 中注解@service("u")
@Autowired
public void setUserDAO(@Qualifier("u")UserDAO dao) {
this.dao = dao;
}
//此段代码指定了注入的bean的 id/name 为"u"
- @Resource的作用相当于@Autowired。@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,
而@Resource默认按 byName自动注入罢了。默认注入名字为类名,首字母小写
5.三级缓存 循环依赖问题
GetBean()
方法里面有个getSingletion()
方法,在这个方法里面向三个缓存依次取值,一级缓存singletionObjects
踏实currentHahMap,二级缓存earlySingletionObjects
三级缓存singletionFactories
,剩下两个都是hashMap
- singletonObjects:第一级缓存,里面放置的是已经实例化好的单例对象;
- earlySingletonObjects:第二级缓存,里面存放的是提前曝光的单例对象;
- singletonFactories:第三级缓存,里面存放的是将要被实例化的对象的对象工厂。
- 所以当一个Bean调用构造函数进行实例化后,即使set属性还未填充,就可以通过三级缓存向外暴露依赖的引用值进行set(所以循环依赖问题的解决也是基于Java的引用传递),这也说明了另外一点,基于构造函数的注入,如果有循环依赖,Spring是不能够解决的
Spring通过将实例化后的对象提前暴露给Spring容器中的singletonFactories,解决了循环依赖的问题。
对于“prototype”作用域Bean,Spring容器无法完成依赖注入,因为“prototype”作用域的Bean,Spring容器不进行缓存,因此无法提前暴露一个创建中的Bean。因此原型模式的循环依赖会报错
6.spring中bean的作用域有哪些
- singleton: 单例 唯一bean实例,spring中的bean默认都是单例的
- prototype: 每次请求都会创建新的bean实例
- request: 每一次http请求都会产生一个新的bean,该bean只在当前HTTP request内有效
- session: 每次HTTP请求都会产生新的bean,只在当前session内有效
- global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,spring5已经没有了
7.spring中单例bean的线程安全问题
单例bean存在线程安全问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会引发安全问题
常见的两种解决方法
- 在bean对象中尽量避免定义可变的成员变量
- 在类中定义一个
ThreadLocal
成员变量,将需要的可变成员变量保存在ThreadLocal
中
8.Spring 中的 bean 生命周期
- Bean 容器找到配置文件中 Spring Bean 的定义。
- Bean 容器利用 Java Reflection API 创建一个Bean的实例。
- 如果涉及到一些属性值 利用 set()方法设置一些属性值。
- 如果 Bean 实现了 BeanNameAware 接口,调用setBeanName()方法,传入Bean的名字。
- 如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例。
- 如果Bean实现了 BeanFactoryAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoade r对象的实例。
与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法。 - 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
- 如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。
- 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
- 如果有和加载这个 Bean的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
- 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
- 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法
9.@Component 和 @Bean 的区别
- 作用对象不同
@Component
作用于类,@Bean
作用于方法 - @Component通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean告诉了Spring这是某个类的示例,当我需要用它的时候还给我。
@Bean
注解的自定义性更强,很多地方只能用bean,比如引用第三方类库的夯实后需要装配的spring容器时,就要使用@Bean
注解来实现
10.spring管理事务的方式,
- 1,编程式事务–代码实现
- 2.声明式事务–配置文件中使用,注解实现
11.spring是什么
- spring是一个轻量级的开源的J2EE框架,他是一个容器框架,用来装javabean对象,中间层框架可以起一个连接作用,比如把mybatis和mysql粘合在一起使用,
- spring是一个轻量级的控制反转ioc和面向切面aop的容器框架
- 通过控制反转的技术轻松达到解耦的目的
- 提供面向切面变成的丰富的支持,允许通过分离应用的业务逻辑与系统级服务进行内聚行的开发
- 包含并管理应用对象bean的配置和生命周期,这个意义上是一个容器
- 将简单的组件配置,组合成为复杂的应用,这个意义上是一个框架.
12.如何实现一个start
- 1.引入
spring-boot-autoconfigure
依赖 - 2.创建配置实体类
- 3.创建自动配置类,设置实例化条件(
@Conditionalxxx
注解,可不设置),并注入容器 - 4.在META-INF文件下创建
spring.factories
文件,激活自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\对应的需要注入的自动配置类
- 5.在maven仓库发布starter
BeanFactory 和ApplicationContext的区别
-
BeanFactory和ApplicationContext都是接口,并且ApplicationContext间接继承了BeanFactory。
-
BeanFactory是Spring中最底层的接口,提供了最简单的容器的功能,只提供了实例化对象和获取对象的功能,而ApplicationContext是Spring的一个更高级的容器,提供了更多的有用的功能。
-
ApplicationContext提供的额外的功能:获取Bean的详细信息(如定义、类型)、国际化的功能、统一加载资源的功能、强大的事件机制、对Web应用的支持等等。
-
加载方式的区别:BeanFactory采用的是延迟加载的形式来注入Bean;ApplicationContext则相反的,它是在Ioc启动时就一次性创建所有的Bean,好处是可以马上发现Spring配置文件中的错误,坏处是造成浪费
-
applicationContext虽然继承了beanFactory但是不应该看作是实现了beanfactory,
因为它内部持有了一个beanfactory的实现类defaultListableBeanFactory