日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
工具類如何獲取到Spring容器中的Bean?

1. Aware 接口

當(dāng)然這只是一個理論,在實際開發(fā)中,我們往往要用到 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.
*
*

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 {

}

從這個接口的注釋中,我們也能大概看出來,這個接口的子類,主要是提供了一些只有一個參數(shù)的 set 方法,通過這些方法可以讓 Spring 容器感知到某一件事情。

Aware 的實現(xiàn)有很多,大的方向來說主要有如下一些:

每一個 Aware 的作用如下:

  • ApplicationEventPublisherAware:實現(xiàn)該接口的對象可以獲取事件發(fā)布的能力。
  • ServletContextAware:實現(xiàn)該接口的對象可以獲取到 ServletContext 對象。
  • MessageSourceAware:實現(xiàn)該接口的對象可以獲取到 MessageSource 對象,MessageSource 支持多消息源,主要用于主要用于國際化。
  • ResourceLoaderAware:實現(xiàn)該接口的對象可以獲取到一個 ResourceLoader,Spring ResourceLoader 則為我們提供了一個統(tǒng)一的 getResource() 方法來通過資源路徑檢索外部資源,例如文本文件、XML 文件、屬性文件或圖像文件等。
  • ApplicationStartupAware:實現(xiàn)該接口的對象可以獲取到一個 ApplicationStartup 對象,這個比較新,是 Spring 5.3 中新推出的,通過 ApplicationStartup 可以標(biāo)記應(yīng)用程序啟動期間的步驟,并收集有關(guān)執(zhí)行上下文或其處理時間的數(shù)據(jù)。
  • NotificationPublisherAware:實現(xiàn)該接的對象可以獲取到一個 NotificationPublisher 對象,通過該對象可以實現(xiàn)通知的發(fā)送。
  • EnvironmentAware:實現(xiàn)該接口的對象可以獲取到一個 Environment 對象,通過 Environment 可以獲取到容器的環(huán)境信息。
  • BeanFactoryAware:實現(xiàn)該接口的對象可以獲取到一個 BeanFactory 對象,通過 BeanFactory 可以完成 Bean 的查詢等操作。
  • ImportAware:實現(xiàn)該接口的對象可以獲取到一個 AnnotationMetadata 對象,ImportAware 接口是需要和 @Import 注解一起使用的。在 @Import 作為元注解使用時,通過 @Import 導(dǎo)入的配置類如果實現(xiàn)了 ImportAware 接口就可以獲取到導(dǎo)入該配置類接口的數(shù)據(jù)配置。
  • EmbeddedValueResolverAware:實現(xiàn)該接口的對象可以獲取到一個 StringValueResolver 對象,通過 StringValueResolver 對象,可以讀取到 Spring 容器中的 properties 配置的值(YAML 配置也可以)。
  • ServletConfigAware:實現(xiàn)該接口的對象可以獲取到一個 ServletConfig 對象,不過這個似乎沒什么用,我們很少自己去配置 ServletConfig。
  • LoadTimeWeaverAware:實現(xiàn)該接口的對象可以獲取到一個 LoadTimeWeaver 對象,通過該對象可以獲取加載 Spring Bean 時織入的第三方模塊,如 AspectJ 等。
  • BeanClassLoaderAware:實現(xiàn)該接口的對象可以獲取到一個 ClassLoader 對象,ClassLoader 能干嘛不需要我多說了吧。
  • BeanNameAware:實現(xiàn)該接口的對象可以獲取到一個當(dāng)前 Bean 的名稱。
  • ApplicationContextAware:實現(xiàn)該接口的對象可以獲取到一個 ApplicationContext 對象,通過 ApplicationContext 可以獲取容器中的 Bean、環(huán)境等信息。

這是 Spring 中提供的一堆 Aware。

接下來松哥隨便寫個例子大家來看下 Aware 的用法。

2. BeanFactoryAware

實現(xiàn)該接口的對象可以獲取到一個 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 getBean(String beanName) {
return (T) beanFactory.getBean(beanName);
}
}

有了這個工具類,接下來我們就可以在一個非 Spring 管理的 Bean 中,隨時隨地的查詢 Bean 了,像下面這樣:

UserService userService = BeanUtils.getBean("userService");
userService.hello();

3. TienChin 項目實踐

為什么會有今天這篇文章呢?主要是在松哥最近做的 TienChin 項目中,有一個地方涉及到這塊知識點了,但是有的小伙伴不熟悉,因此就拎出來和大家梳理下。

在 TienChin 項目中,在記錄日志的時候,因為日志是一個延遲任務(wù),所以提前準(zhǔn)備好了相關(guān)的 Bean 已經(jīng)注冊到 Spring 容器中了,像下面這樣:

@Configuration
public class ThreadPoolConfig {

/**
* 執(zhí)行周期性或定時任務(wù)
*/
@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應(yīng)用上下文環(huán)境
*/
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 getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}

/**
* 獲取類型為requiredType的對象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*/
public static T getBean(Class clz) throws BeansException {
T result = (T) beanFactory.getBean(clz);
return result;
}
}

而寫日志的異步任務(wù)工具類,并非一個容器,所以要通過這個工具類獲取相應(yīng)的 Bean,如下:

public class AsyncManager {
/**
* 操作延遲10毫秒
*/
private final int OPERATE_DELAY_TIME = 10;

/**
* 異步操作任務(wù)調(diào)度線程池
*/
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");

/**
* 單例模式
*/
private AsyncManager() {
}

private static AsyncManager me = new AsyncManager();

public static AsyncManager me() {
return me;
}

/**
* 執(zhí)行任務(wù)
*
* @param task 任務(wù)
*/
public void execute(TimerTask task) {
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
}

有了 SpringUtils 我們就可以在一個非 Spring 容器所管理的 Bean 中,獲取到 Spring 容器中的 Bean 了。


分享名稱:工具類如何獲取到Spring容器中的Bean?
鏈接分享:http://m.5511xx.com/article/djddish.html