小伙伴们知道,工具Spring 容器最大的类何特点在于所有的 Bean 对于 Spring 容器的存在是没有意识的,因此我们常说理论上你可以无缝将 Spring 容器切换为其他容器(然而在现实世界中,到S的我们其实没有这样的器中选择,除了 Spring 容器,工具难道还有更好用的类何?)。
当然这只是到S的一个理论,在实际开发中,器中我们往往要用到 Spring 容器为我们提供的工具诸多资源,例如想要获取到容器中的类何配置、获取到容器中的到S的 Bean 等等。在这种情况下,器中就需要 Spring 容器中的工具 Bean 真正的意识到 Spring 容器的存在,才能要到这些东西,类何那么如何让一个 Bean 意识到 Spring 容器的到S的存在呢?
这就依赖于 Spring 容器给我们提供的网站模板各种 Aware 接口了。
/
*** A marker superinterface indicating that a bean is eligible to be notified by the
* Spring container of a particular framework object through a callback-style method.
* The actual method signature is determined by individual subinterfaces but should
* typically consist of just one void-returning method that accepts a single argument.
**
Note that merely implementing {@link Aware} provides no default functionality.
* Rather, processing must be done explicitly, for example in a
* {@link org.springframework.beans.factory.config.BeanPostProcessor}.
* Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
* for an example of processing specific {@code *Aware} interface callbacks.
** @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
*/
public interface Aware {
}从这个接口的注释中,我们也能大概看出来,这个接口的子类,主要是提供了一些只有一个参数的 set 方法,通过这些方法可以让 Spring 容器感知到某一件事情。
Aware 的实现有很多,大的方向来说主要有如下一些:

每一个 Aware 的作用如下:
ApplicationEventPublisherAware:实现该接口的对象可以获取事件发布的能力。ServletContextAware:实现该接口的对象可以获取到 ServletContext 对象。MessageSourceAware:实现该接口的对象可以获取到 MessageSource 对象,MessageSource 支持多消息源,主要用于主要用于国际化。ResourceLoaderAware:实现该接口的对象可以获取到一个 ResourceLoader,Spring ResourceLoader 则为我们提供了一个统一的 getResource() 方法来通过资源路径检索外部资源,例如文本文件、XML 文件、属性文件或图像文件等。ApplicationStartupAware:实现该接口的对象可以获取到一个 ApplicationStartup 对象,这个比较新,云服务器提供商是 Spring 5.3 中新推出的,通过 ApplicationStartup 可以标记应用程序启动期间的步骤,并收集有关执行上下文或其处理时间的数据。NotificationPublisherAware:实现该接的对象可以获取到一个 NotificationPublisher 对象,通过该对象可以实现通知的发送。EnvironmentAware:实现该接口的对象可以获取到一个 Environment 对象,通过 Environment 可以获取到容器的环境信息。BeanFactoryAware:实现该接口的对象可以获取到一个 BeanFactory 对象,通过 BeanFactory 可以完成 Bean 的查询等操作。ImportAware:实现该接口的对象可以获取到一个 AnnotationMetadata 对象,ImportAware 接口是需要和 @Import 注解一起使用的。在 @Import 作为元注解使用时,通过 @Import 导入的配置类如果实现了 ImportAware 接口就可以获取到导入该配置类接口的数据配置。EmbeddedValueResolverAware:实现该接口的对象可以获取到一个 StringValueResolver 对象,通过 StringValueResolver 对象,可以读取到 Spring 容器中的 properties 配置的企商汇值(YAML 配置也可以)。ServletConfigAware:实现该接口的对象可以获取到一个 ServletConfig 对象,不过这个似乎没什么用,我们很少自己去配置 ServletConfig。LoadTimeWeaverAware:实现该接口的对象可以获取到一个 LoadTimeWeaver 对象,通过该对象可以获取加载 Spring Bean 时织入的第三方模块,如 AspectJ 等。BeanClassLoaderAware:实现该接口的对象可以获取到一个 ClassLoader 对象,ClassLoader 能干嘛不需要我多说了吧。BeanNameAware:实现该接口的对象可以获取到一个当前 Bean 的名称。ApplicationContextAware:实现该接口的对象可以获取到一个 ApplicationContext 对象,通过 ApplicationContext 可以获取容器中的 Bean、环境等信息。这是 Spring 中提供的一堆 Aware。
接下来松哥随便写个例子大家来看下 Aware 的用法。
2. BeanFactoryAware实现该接口的对象可以获取到一个 BeanFactory 对象,通过 BeanFactory 可以完成 Bean 的查询等操作。这算是一个比较常见的 Aware 了,我们一起来看下。
这里为了省事,我就在 Spring Boot 中来和大家演示。
首先我们来定义一个简单的 UserService:
@Service
public class UserService {
public void hello() {
System.out.println("hello javaboy!");
}
}然后提供一个工具类:
@Component
public class BeanUtils implements BeanFactoryAware {
private static BeanFactory beanFactory = null;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
BeanUtils.beanFactory = beanFactory;
}
public static 
return (T) beanFactory.getBean(beanName);
}
}有了这个工具类,接下来我们就可以在一个非 Spring 管理的 Bean 中,随时随地的查询 Bean 了,像下面这样:
UserService userService = BeanUtils.getBean("userService");
userService.hello();3. TienChin 项目实践为什么会有今天这篇文章呢?主要是在松哥最近做的 TienChin 项目中,有一个地方涉及到这块知识点了,但是有的小伙伴不熟悉,因此就拎出来和大家梳理下。
在 TienChin 项目中,在记录日志的时候,因为日志是一个延迟任务,所以提前准备好了相关的 Bean 已经注册到 Spring 容器中了,像下面这样:
@Configuration
public class ThreadPoolConfig {
/
*** 执行周期性或定时任务
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService() {
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
new ThreadPoolExecutor.CallerRunsPolicy()) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Threads.printException(r, t);
}
};
}
}
@Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
/
*** Spring应用上下文环境
*/
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext applicationContext;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
/
*** 获取对象
** @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*/
@SuppressWarnings("unchecked")
public static 
return (T) beanFactory.getBean(name);
}
/
*** 获取类型为requiredType的对象
** @param clz
* @return
* @throws org.springframework.beans.BeansException
*/
public static 
T result = (T) beanFactory.getBean(clz);
return result;
}
}而写日志的异步任务工具类,并非一个容器,所以要通过这个工具类获取相应的 Bean,如下:
public class AsyncManager {
/
*** 操作延迟10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;
/
*** 异步操作任务调度线程池
*/
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/
*** 单例模式
*/
private AsyncManager() {
}
private static AsyncManager me = new AsyncManager();
public static AsyncManager me() {
return me;
}
/
*** 执行任务
** @param task 任务
*/
public void execute(TimerTask task) {
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
}有了 SpringUtils 我们就可以在一个非 Spring 容器所管理的 Bean 中,获取到 Spring 容器中的 Bean 了。
相关文章:
香港云服务器IT技术网源码库服务器租用IT资讯网源码下载益华科技亿华云企商汇思维库益强编程舍IT资讯网益强IT技术网极客编程极客码头益华科技亿华互联云站无忧亿华智造码上建站益强前沿资讯编程之道益强科技益强智未来技术快报益华科技亿华云益强数据堂科技前瞻码力社益强编程堂云智核益强智囊团益强科技益华IT技术论坛亿华科技亿华云计算多维IT资讯亿华智慧云汇智坊益强资讯优选
0.2824s , 11749.6875 kb
Copyright © 2025 Powered by 工具类如何获取到 Spring 容器中的 Bean?,亿华互联 滇ICP备2023000592号-16