Spring- ApplicationContextAware实际应用

1,467 阅读2分钟

ApplicationContextAware接口说明

Interface to be implemented by any object that wishes to be notified of the {@link ApplicationContext} that it runs in.
  • 任何期望获取到spring管理的ApplicationContext实例的任何对象需实现的接口

ApplicationContext接口

/**
 * Central interface to provide configuration for an application.
 * This is read-only while the application is running, but may be
 * reloaded if the implementation supports this.
 *
 * <p>An ApplicationContext provides:
 * <ul>
 * <li>Bean factory methods for accessing application components.
 * Inherited from {@link org.springframework.beans.factory.ListableBeanFactory}.
 * <li>The ability to load file resources in a generic fashion.
 * Inherited from the {@link org.springframework.core.io.ResourceLoader} interface.
 * <li>The ability to publish events to registered listeners.
 * Inherited from the {@link ApplicationEventPublisher} interface.
 * <li>The ability to resolve messages, supporting internationalization.
 * Inherited from the {@link MessageSource} interface.
 * <li>Inheritance from a parent context. Definitions in a descendant context
 * will always take priority. This means, for example, that a single parent
 * context can be used by an entire web application, while each servlet has
 * its own child context that is independent of that of any other servlet.
 * </ul>
 *
 * <p>In addition to standard {@link org.springframework.beans.factory.BeanFactory}
 * lifecycle capabilities, ApplicationContext implementations detect and invoke
 * {@link ApplicationContextAware} beans as well as {@link ResourceLoaderAware},
 * {@link ApplicationEventPublisherAware} and {@link MessageSourceAware} beans.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see ConfigurableApplicationContext
 * @see org.springframework.beans.factory.BeanFactory
 * @see org.springframework.core.io.ResourceLoader
 */
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver
  • 中央接口,为应用程序提供配置。 在应用程序运行时,它是只读的,但是如果实现支持,则可以重新加载
  • ApplicationContext提供:
    • 用于访问应用程序组件的Bean工厂方法。继承自{@link org.springframework.beans.factory.ListableBeanFactory}
    • 以通用方式加载文件资源的能力。继承自{@link org.springframework.core.io.ResourceLoader}接口
    • 将事件发布到注册的侦听器的能力。继承自{@link ApplicationEventPublisher}接口。
    • 解决消息的能力,支持国际化。继承自{@link MessageSource}接口。
    • 从父上下文继承。 在后代上下文中的定义将始终优先。 例如,这意味着整个Web应用程序都可以使用单个父上下文,而每个servlet都有其自己的子上下文,该子上下文独立于任何其他servlet的子上下文
  • 除了标准的{@link org.springframework.beans.factory.BeanFactory}生命周期功能之外,ApplicationContext实现还检测并调用{@link ApplicationContextAware} bean以及{@link ResourceLoaderAware},{@ link ApplicationEventPublisherAware}和{@link MessageSourceAware } bean

应用场景

  • 一些Converter类中,需要在静态方法中获取到spring管理的某个bean。由于Converter类不属于spring管理,所以无法通过@Autowired、@Resource方式进行注入相关依赖。可通过ApplicationContext.getBean方法获取
  • 使用@Cacheable、@Transactional等注解时,如果对象的方法是内部调用(即this引用)时,会导致代理失效,从而注解不起作用。可通过ApplicationContext.getBean方法获取,然后调用对应的方法,则可以使代理生效

代码 - 获取bean的工具类

  • 实现ApplicationContextAware接口,内部持有ApplicationContext对象实例,并通过静态方法对外提供获取bean的能力
  • 代码如下:
@Component
public class SpringContext implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContext.applicationContext = applicationContext;
    }

    public static <T> T getBean(String name, Class<T> clazz) {
        return applicationContext.getBean(name, clazz);
    }

    public static <T> T getBean(Class<T> clazz) {
        try {
            return applicationContext.getBean(clazz);
        } catch (RuntimeException e) {
            return null;
        }
    }

    /**
     * 获取当前激活的环境
     *
     * @return
     */
    public static String getActiveProfile() {
        return applicationContext.getEnvironment().getActiveProfiles()[0];
    }
}