由于一些遗留代码,我需要访问无法自动装配bean的非spring类中的spring bean(spring boot 2,junit 5)。为此,大多数人建议像
那样实现ApplicationContextAware
@Component
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
在生产代码中可以正常工作。但是我有一些使用@MockBean
批注的测试,导致spring为此创建了一个新的应用程序上下文,这将触发setApplicationContext
的{{1}}。如果此后的另一个测试没有任何模拟的Bean,则原始应用程序上下文将被重用,因为它已被spring缓存。问题在于,重用应用程序上下文不会触发ApplicationContextAware
,因此我无法从setApplicationContext
获取任何有效的bean,因为BeanUtil
拥有过时的应用程序上下文,请参见Spring的{{1 }}
BeanUtil
更多正式流程:
DefaultCacheAwareContextLoaderDelegate
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedContextConfiguration) {
synchronized (this.contextCache) {
ApplicationContext context = this.contextCache.get(mergedContextConfiguration);
if (context == null) {
try {
context = loadContextInternal(mergedContextConfiguration);
if (logger.isDebugEnabled()) {
logger.debug(String.format("Storing ApplicationContext in cache under key [%s]",
mergedContextConfiguration));
}
this.contextCache.put(mergedContextConfiguration, context);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to load ApplicationContext", ex);
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Retrieved ApplicationContext from cache with key [%s]",
mergedContextConfiguration));
}
}
this.contextCache.logStatistics();
return context;
}
}
ApplicationContextAware
ApplicationContextAware
中是否有任何方式可以通知您,再次使用了缓存的应用程序上下文?