spring面试题
spring IOC的理解
控制反转将bean的创建 配置 和销毁 交给spring容器, 在需要使用的地方使用依赖注入获取bean,这样实现了bean创建和使用的解耦合
依赖注入的方式主要有
- 注解式autowired`` resource qualified
- setter注入
- 构造器注入
构造器注入是首选,这种注入方式可以声明属性是private final类型,保证不会被更改,符合springbean 无状态的要求
spring bean的生命周期
- spring对bean进行实例化
- Spring将值和bean的引用注入到bean对应的属性中
- 如果bean实现了BeanNameAware接口,Spring将bean的ID传递getsetBeanName()方法
- 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将备案所在的应用上下文传入进来
- 如果bean实现了BeanPostProcessor接口,Spring将调用postProcessBeforeInitialization()方法
- 如果bean实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法
- 如果bean实现了了BeanPostProcessor接口,Spring将调用他们的postProcessorAfterInitialization()方法
- bean初始化完成
- bean如果实现了DisposabelBean接口,Spring将调用destroy接口
spring如何解决循环依赖问题
使用三级map缓存,一级map缓存实例,二级缓存已创建但是未初始化的bean,三级map缓存对象创建工厂
Spring通过将实例化后的对象提前暴露给Spring容器中的singletonFactories,解决了循环依赖的问题。
ab两个bean相互依赖,a 初始化但是未完成状态处于二级map中,初始化b时可以找到存在二级map中a对象完成初始化,接着再初始化a
达到相互注入的目的
SpringAOP
spring aop 面向切面编程,使用动态代理运行时织入
- 代理对象分为两种 静态代理和动态代理 静态代理可以通过aspectJ和继承重写类实现,在编译阶段代理对象类就已经存在
- 静态代理一个代理类只能为一个接口创建代理,不适合通用功能的实现,动态代理可以简化编码工作 解耦合
- 动态代理 运行时织入程序 可以通过jdk和cglib 通过反射创建代理类实现
- jdk只提供基于接口的代理,代理类生成继承了Proxy类,java不支持多继承,只能通过实现目标接口的方式,通过反射执行方法
- cglib通过继承创建子类拦截所有父类方法的调用,并织入横切逻辑
BeanFactory和ApplicationContext区别
beanFactory是顶级接口,是ApplicationContext是其子接口
ClassPathXmlApplicationContext extends AbstractXmlApplicationContext
ApplicationContext是ioc容器初始化的入口, 项目启动就会初始化bean
BeanFactory 是懒加载 只有在调用getBean方法时才睡初始化生成Bean
参考 https://www.cnblogs.com/swordfall/p/12880809.html