公众号 [ JavaQ ] 原创, 专注分享 Java 基础原理分析, 实战技术, 微服务架构, 分布式系统构建, 诚邀点赞关注!
面试官 : 如果想在一个 Bean 被实例化时做一些额外的初始化操作, 如何实现?
小小白 : 有两种方法, 一个是使用 @PostConstruct 注解或 init-method 指定初始化方法, 另一个是这个 Bean 实现 InitializingBean 接口, InitializingBean 接口中只有一个 afterPropertiesSet 方法, 这个方法是在 Bean 的属性都设置值后被调用, 用于完成一些初始化工作.
面试官 :afterPropertiesSet 方法和 init-method 指定的方法执行的先后顺序有了解过吗?
小小白 :afterPropertiesSet 方法先执行, init-method 指定的方法后执行.
面试官 : 像这种初始化方法, 在使用上有什么需要注意的?
小小白 : 这两种方式都是用于完成一些初始化工作, 所以相应的方法中尽量不要编写一些复杂且执行时间很长的逻辑, 例如网络请求, IO 操作.
面试官 : 那如果想在 Bean 被销毁回收的时候做一些额外的操作, 如何操作?
小小白 : 同样也是两种方法, 一个是使用 @PreDestroy 注解或 destroy-method 指定销毁方法, 另一个是这个 Bean 实现 DisposableBean 接口, DisposableBean 接口中只有一个 destroy 方法, 该方法会在 Bean 被销毁, 生命周期结束之前被调用, 用于做一些销毁的收尾工作. DisposableBean 接口的 destroy 方法先于 destroy-method 指定的方法先执行.
面试官 : 如果想在 Bean 被加载的过程中获取 Spring 的应用上下文 ApplicationContext, 如何实现?
小小白 :Spring 框架中有一个 ApplicationContextAware 接口, 接口有一个 setApplicationContext 方法, 只要 Bean 实现了 ApplicationContextAware 接口, 就可以在该 Bean 被加载的过程中获取 Spring 的应用上下文 ApplicationContext, 通过 ApplicationContext 可以获取 Spring 容器内的很多信息.
面试官 : 说到获取 Spring 的应用上下文 ApplicationContext, 在基于 Spring MVC 的 web 应用中, 如何获取 WebApplicationContext?
小小白 :Spring 框架提供了一个 WebApplicationContextUtils 工具类, 通过这个工具类的 getWebApplicationContext 方法可以获取到.
面试官 : 如果想在 Bean 被加载的过程中获取加载该 Bean 的 BeanFactory, 如何实现?
小小白 :Spring 框架中有一个 BeanFactoryAware 接口, 接口中有一个 setBeanFactory 方法. 实现了 BeanFactoryAware 接口的 Bean, 可以在该 Bean 被加载的过程中获取加载该 Bean 的 BeanFactory, 同时也可以获取这个 BeanFactory 中加载的其它 Bean.
面试官 : 那这个 setBeanFactory 方法在什么时候被调用的?
小小白 : 在 Bean 实例化后, Setter 方法之前调用.
面试官 : 如果要定制 Bean 的实例化逻辑, 如何实现?
小小白 :Spring 框架的 FactoryBean 接口可以实现 Bean 实例化的个性定制, 让 Spring 容器加载我们想要的 Bean. 实现了 FactoryBean 接口的类, 可以通过实现 getObject 方法, 实现加载我们想要的 Bean.
面试官 : 说到 FactoryBean,BeanFactory 和 FactoryBean 有什么区别?
小小白 :BeanFactory 定义了 IoC 容器的最基本形式, 并提供了 IoC 容器应遵守的的最基本的接口, 也就是 Spring IoC 所遵守的最底层和最基本的编程规范, 它只是个接口, 并不是 IoC 容器的具体实现. 它的职责包括: 实例化, 定位, 配置应用程序中的对象及建立这些对象间的依赖. 再来说说 FactoryBean, 一般情况下, Spring 通过反射机制利用 bean 的 class 属性实例化 Bean, 然而在某些情况下, 实例化 Bean 过程比较复杂, 如果按照传统的方式, 则需要在 bean 的定义中提供大量的配置信息, 而配置这种方式的灵活性是受限的, 这时采用编码的方式可能会是一个比较合适的方案, Spring 为此提供了 FactoryBean 的工厂类接口, 用户可以通过实现该接口定制实例化 Bean 的逻辑.
面试官 : 有了解过 Spring 中的 BeanPostProcessor 接口吗?
小小白 :BeanPostProcessor 接口中有两个方法, 分别为 postProcessBeforeInitialization 和 postProcessAfterInitialization. 实现了 BeanPostProcessor 接口的类, 会在每个 Bean 初始化 (即调用 setter) 之前和之后, 分别调用这个类中的 postProcessBeforeInitialization 方法和 postProcessAfterInitialization 方法, 实现初始化的逻辑控制.
面试官 : 如果想在初始化前修改 bean 的属性, 如何实现?
小小白 :BeanFactoryPostProcessor 接口中只有 postProcessBeanFactory 方法. 实现了该接口的类, 可以在 Bean 被创建之前, 获取容器中 Bean 的定义信息, 并且可以进行修改. 实现类中的 postProcessBeanFactory 方法只会被执行一次, 且先于 BeanPostProcessor 接口的方法.
面试官 : 如果想在 Bean 实例化调用构造函数前后做一些额外操作, 如何实现?
小小白 :Spring 框架的 InstantiationAwareBeanPostProcessor 接口中, 常用的方法是 postProcessBeforeInstantiation 和 postProcessAfterInstantiation. 每个 Bean 的实例化 (即调用构造函数) 之前和之后, 会分别调用实现了该接口的类中的 postProcessBeforeInstantiation 和 postProcessAfterInstantiation 方法, 所以只要自定义一个实现 InstantiationAwareBeanPostProcessor 接口的类, 实现接口中的这两个方法, 在这两个方法中就可以做额外的操作了.
往期推荐 :
Spring 声明式事务处理的实现原理, 来自面试官的穷追拷问
Spring MVC 相关面试题就是无底洞, 反正我是怕了
说实话, 面试这么问 Spring 框架的问题, 我快扛不住了
没使用加号拼接字符串, 面试官竟然问我为什么
面试官一步一步的套路你, 为什么 SimpleDateFormat 不是线程安全的
都说 ThreadLocal 被面试官问烂了, 可为什么面试官还是喜欢继续问
Java 注解是如何玩转的, 面试官和我聊了半个小时
如何去除代码中的多次 if 而引发的一连串面试问题
三分钟快速搞定 Git 常规使用
String 引发的提问, 我差点跪了
就写了一行代码, 被问了这么多问题
面试官: JVM 对锁进行了优化, 都优化了啥?
synchronized 连环问
点点 "在看" 呗
来源: http://www.tuicool.com/articles/EFfYviF