成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

工具類如何獲取到 Spring 容器中的 Bean?

開發 開發工具
當然這只是一個理論,在實際開發中,我們往往要用到 Spring 容器為我們提供的諸多資源,例如想要獲取到容器中的配置、獲取到容器中的 Bean 等等。在這種情況下,就需要 Spring 容器中的 Bean 真正的意識到 Spring 容器的存在,才能要到這些東西,那么如何讓一個 Bean 意識到 Spring 容器的存在呢?

1. Aware 接口

小伙伴們知道,Spring 容器最大的特點在于所有的 Bean 對于 Spring 容器的存在是沒有意識的,因此我們常說理論上你可以無縫將 Spring 容器切換為其他容器(然而在現實世界中,我們其實沒有這樣的選擇,除了 Spring 容器,難道還有更好用的?)。

當然這只是一個理論,在實際開發中,我們往往要用到 Spring 容器為我們提供的諸多資源,例如想要獲取到容器中的配置、獲取到容器中的 Bean 等等。在這種情況下,就需要 Spring 容器中的 Bean 真正的意識到 Spring 容器的存在,才能要到這些東西,那么如何讓一個 Bean 意識到 Spring 容器的存在呢?

這就依賴于 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.
*
* <p>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 <T> T getBean(String beanName) {
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 <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}

/**
* 獲取類型為requiredType的對象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
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 了。

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2023-01-13 07:41:20

BeanSpring容器

2023-11-03 08:19:18

SpringBean容器

2009-06-17 17:20:14

BeanFactorySpring

2022-12-27 08:12:27

IOC容器Bean

2024-05-29 08:19:03

2009-06-17 17:04:37

BeanFactorySpring

2024-02-23 10:33:34

SpringBean容器

2023-07-26 00:43:31

2011-03-18 09:27:00

Spring

2022-07-20 07:32:46

Prototypevalue?容器

2021-03-08 08:40:25

Spring Bean 創建單例對象

2022-07-21 09:31:58

Actuator密碼框架

2021-04-29 07:18:21

Spring IOC容器單例

2022-04-27 08:19:53

Docker容器Linux

2024-05-28 07:55:31

SpringBean用域

2021-05-11 07:42:59

BeanSpring屬性

2023-07-29 22:11:58

Spring容器Component

2022-01-10 09:43:55

CCleanerWindows 11微軟商店

2011-04-02 15:25:41

Spring

2009-01-30 09:12:11

SpringApplicationJavaWeb
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 福利网址| 中国av在线免费观看 | 久久精品国产清自在天天线 | 一区二区日韩 | 国产亚洲精品美女久久久久久久久久 | 99福利视频 | 久久久久久一区 | 亚洲一区免费视频 | 国产精品一区二区免费看 | 欧美三级三级三级爽爽爽 | 99精品视频免费观看 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 久久精品女人天堂av | 日本精品视频 | 国产精品久久一区二区三区 | 免费毛片网站在线观看 | 毛片网在线观看 | 一级毛片免费看 | 精久久久 | 欧美日韩精品一区二区三区四区 | 韩日一区二区三区 | 韩日精品在线观看 | 国产成人免费视频网站高清观看视频 | 亚洲综合久久精品 | h视频在线看 | 999国产精品视频免费 | 午夜视频免费在线 | 成人h电影在线观看 | 国产精品久久久久一区二区三区 | 一级日批片 | 亚洲一区二区精品 | 亚洲成人精品一区 | 亚洲精选一区二区 | 国产成人99久久亚洲综合精品 | 一区二区中文字幕 | 亚洲狠狠丁香婷婷综合久久久 | 成人午夜精品一区二区三区 | 欧美二区三区 | 中国大陆高清aⅴ毛片 | 国产一区二区视频在线 | 亚洲精品一区二区三区蜜桃久 |