Java面试常考——Spring框架

Spring

Spring ——是一个轻量级的控制反转和面向切面的容器

Spring 的作用
  • 在 JavaEE 开发中,支持 JavaBean 开发方式,使应用面向接口开发,充分支持面向对象的设计方法
  • Spring通过IoC容器实现对象耦合关系的管理,并实现依赖反转,将对象之间的依赖关系交给IoC容器,实现解耦
什么是 IOC ?
  • IOC 是控制反转
  • 在传统开发中,我们在对象内部用 new 创建依赖对象,是主动控制对象
  • IOC是有一个专门的容器创建依赖对象,由 Spring 控制和管理这些对象,对象的创建由程序自己控制
  • Spring 容器在初始化时先读取配置文件,根据配置文件创建对象(getBean()方法)存入容器,程序使用时再从 IOC 容器中取出需要的对象。
  • IOC 与 DI 的关系:控制反转是通过 XML 文件或注解去生成并获取特定对象的方式。在 Spring 中实现控制反转的是 IOC 容器,他的实现方法是依赖注入 DI。
什么是 AOP ?
  • AOP,一般称为面向切面,作为面向对象的一种补充
  • 用于把与业务无关的,但对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块
  • 减少系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性
  • AOP实现的关键在于代理模式,主要使用动态代理
  • Spring AOP 使用的动态代理,就是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
BeanFactory和ApplicationContext有什么区别
  • BeanFactory 和 ApplicationContext 是 Spring 的两大核心接口,都可以当做 Spring 的容器
  • BeanFactory是Spring里面最底层的接口,是IoC的核心,定义了IoC的基本功能,包含了各种Bean的定义、加载、实例化,依赖注入和生命周期管理。
  • ApplicationContext 接口是 BeanFactory 的子类,除了提供BeanFactory所具有的功能外,还提供了更完整的功能:
    • 继承MessageSource,因此支持国际化。
    • 资源文件访问,如URL和文件(ResourceLoader)。
    • 同时加载多个配置文件 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
    • 提供在监听器中注册bean的事件
  • 具体区别:
    • BeanFactroy采用的是延迟加载形式来注入Bean的,只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。
    • ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。
    • ApplicationContext启动后预载入所有的单实例Bean,所以在运行的时候速度比较快,因为它们已经创建好了。相对于BeanFactory,ApplicationContext 唯一的不足是占用内存空间,当应用程序配置Bean较多时,程序启动较慢。
Spring 的使用
  • 加入依赖
  • 创建类:接口、实现类、没有接口的类
  • 创建 Spring 的配置文件,使用声明对象
  • 通过 ApplicationContext 接口和他的实现类 ClassPathXmlApplicationContext 的 getBean()方法使用容器中的对象
Spring Bean 的生命周期
  • 总体:实例化(Instantiation)–属性赋值(Populate)–初始化(Initialization)–销毁(Destruction)
  • 实例化Bean:
    • 对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
    • 对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。
  • 设置对象属性(依赖注入):实例化后的对象被封装在BeanWrapper对象中,然后 Spring 根据 BeanDefinition 中的信息 以及 通过BeanWrapper提供的设置属性的接口完成属性设置与依赖注入。
  • 处理Aware接口:Spring 会检测该对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的一些资源:
    • 如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,传入Bean的名字;
    • 如果这个Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
    • 如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
    • 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;
  • BeanPostProcessor前置处理:如果想对Bean进行一些自定义的前置处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
  • InitializingBean:如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。
  • init-method:如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
  • BeanPostProcessor后置处理:如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;这时 Bean 就被正确创建了
  • DisposableBean:当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;
  • destroy-method:最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
Spring 框架中的 Bean 如何保证线程安全?
  • 对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。
  • 对于singleton作用域的Bean,所有的线程都共享一个单例实例的Bean,因此是存在线程安全问题的。
    • 如果单例Bean是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Controller类、Service类和Dao等,这些Bean大多是无状态的,只关注于方法本身。
    • 对于有状态的bean(比如Model和View),就需要自行保证线程安全,最容易的解决办法就是将有状态的bean的作用域由“singleton”改为“prototype”。也可以采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本,不同线程只操作自己线程的副本变量。
Spring 中 bean 的作用域
  • singleton:默认作用域,单例bean,每个容器中只有一个bean的实例。
  • prototype:为每一个bean请求创建一个实例。
  • request:为每一个request请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
  • session:与request范围类似,同一个session会话共享一个实例,不同会话使用不同的实例。
  • global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会话共享的存储变量的话,那么这全局变量需要存储在global-session中。
Spring 常用注解
  • @Autowired 与 @Resource 比较:
    • @Autowired 与 @Resource 都考研用来装配 bean
    • @Autowired 默认情况下必须要求依赖对象不能为 null
    • @Resource 默认按照名称装配对象,可以通过 name 属性指定装配的类
    • @Autowired 先执行 byType 方式注入对象,@Resource 先执行byName 方式注入对象

(持续更新中,建议收藏)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值