Aware 接口
在Spring中,除了使用注解来进行依赖注入以外,还可以通过实现Aware接口来获取Spring容器的一些重要组件的实例。
其中,Aware接口属于Spring框架中的一个拓展接口,它定义了一些特定的方法,用于获取Spring容器中的一些组件实例。通过实现这些Aware接口,可以达到获取Spring容器中组件的目的。
例如下面的几个接口:
- BeanNameAware:获取当前Bean在Spring容器中的name属性
- BeanClassLoaderAware:获取当前Bean的类加载器
- BeanFactoryAware:获取BeanFactory实例
- ResourceLoaderAware:获取资源加载器
- ServletContextAware:获取ServletContext对象
- MessageSourceAware:获取MessageSource对象
这些Aware接口可以帮助开发者快速获取Spring容器中需要的组件,使代码更加简洁和高效。
InitializingBean 接口
nitializingBean接口是Spring框架的一个拓展接口,可以用于在Bean初始化完成后,执行一些特定的操作。
通过实现InitializingBean接口,可以在Bean初始化完成后,进行一些统一的初始化操作,避免了在每个Bean内部进行初始化操作,提高了代码的复用性。
演示 - Aware 接口及 InitializingBean 接口
1.Aware 接口
- 在我们自己创建的MyBean上实现一个BeanNameAware接口
- 重写接口中抽象方法
- A06中注册MyBean.class查看运行结果
MyBean
A06
运行结果:
在这个我们注册的MyBean初始化之前就会调Aware接口中我们实现的方法,在我们的例子中获得了BeanName并打印日志,在实现其他的Aware接口操作也是一样的
InitializingBean 接口
第一步在我们自己创建的MyBean上实现一个InitializingBean接口,后面两部与上面一样
结果(先执行Aware接口重写的方法,在执行InitializingBean接口重写的方法)
问题:这些实现我们可以用注解完成,为什么还要有这些接口呢
有同学说: Aware接口实现的一些功能用 @Autowired 就能实现啊, 为啥还要用 Aware 接口呢
简单地说:
1. @Autowired 的解析需要用到 bean 后处理器, 属于扩展功能
2. 而 Aware 接口属于内置功能, 不加任何扩展, Spring 就能识别
某些情况下, 扩展功能会失效, 而内置功能不会失效
例1: 你会发现用 Aware 注入 ApplicationContext 成功, 而 @Autowired 注入 ApplicationContext 失败
我们在MyBean中加入利用@Autowired注入ApplicationContext 以及PostConstruct的演示带代码,再运行一下A06:
结果会发现根本没有调用上面的代码,但是发现用 Aware 的方法以及 InitializingBean的方法任然生效
如果想要注解生效,我们还需要额外加后处理器(A06中):
在运行可以发现,利用注解的实现也打印出来了:
收获
- Aware 接口提供了一种【内置】 的注入手段,例如
- BeanNameAware 注入 bean 的名字
- BeanFactoryAware 注入 BeanFactory 容器
- ApplicationContextAware 注入 ApplicationContext 容器
- EmbeddedValueResolverAware 注入 ${} 解析器
- InitializingBean 接口提供了一种【内置】的初始化手段
- 对比
- 内置的注入和初始化不受扩展功能的影响,总会被执行
- 而扩展功能受某些情况影响可能会失效
- 因此 Spring 框架内部的类常用内置注入和初始化