美文网首页
Aware接口

Aware接口

作者: 要不再等等 | 来源:发表于2019-05-24 17:10 被阅读0次

这个是spring-beans包中的概念,正常情况下我们使用bean是不需要考虑容器相关的特性的,所以基本在项目中不会接触这个接口,但是这个接口是获取容器相关属性的核心,比如自己定一个一个bean,然后想在这个bean中获取applicationContext或者beanName等属性,那么我们就需要了解Aware接口相关的特性了。我先说下源码中如何获取spring容器相关特性,然后再举个例子说明下。
1.spring容器启动时会调用AbstractApplicationContext类的prepareBeanFactory方法,其中会定义bean的后置处理器ApplicationContextAwareProcessor

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

2.bean在初始化前会调用一次ApplicationContextAwareProcessor类的postProcessBeforeInitialization方法

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;
        if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
                    return null;
                }
            }, acc);
        } else {
            this.invokeAwareInterfaces(bean);
        }

        return bean;
    }

3.注意postProcessBeforeInitialization方法中具体的invoke方法,如果实现Aware接口会继续判断实现了具体的什么接口,执行对应接口的方法。

private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
            }

            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(new ApplicationContextAwareProcessor.EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
            }

            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
            }

            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
            }

            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
            }

            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }

    }

举个例子,MyApplicationContextAware实现了ApplicationContextAware接口,那么在初始化前会调用setApplicationContext方法,则可以拿到ApplicationContext

@Service
public class MyApplicationContextAware implements ApplicationContextAware {
    private ApplicationContext applicationContext;

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

    public ApplicationContext getApplicationContext(){
        return applicationContext;
    }
}

再举个例子,可以拿到对应bean的beanName

@Component
public class MyBeanNameAware implements BeanNameAware {
    private BeanName beanName;

    @Override
    public void setBeanName(BeanName beanName) throws BeansException {
        this.beanName = beanName;
    }

    public BeanName getBeanName(){
        return beanName;
    }
}

相关文章

  • Aware Mode

    Aware接口 Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后,可以...

  • Spring5IOC容器解析——Aware接口

    Aware Aware 是 Spring 中的一个根接口,继承该接口的子接口有很多,但是该接口没有任何方法,所以大...

  • Spring知识点整理(持续更新)

    Aware接口使用 Spring中Aware.java是个没有任何方法的接口,有很多子接口,常见的比如BeanNa...

  • Aware接口

    Aware 接口是 Spring 框架开放调用组件能力的接口 使用 ApplicationContext 这样我们...

  • Aware接口

    这个是spring-beans包中的概念,正常情况下我们使用bean是不需要考虑容器相关的特性的,所以基本在项目中...

  • spring中Aware后缀

    aware: 意识到的;知道的; spring中带有Aware后缀的接口主要是和bean有关,实现了Aware后...

  • Spring实现Aware接口,完成对IOC容器的感知

    aware主要有以下感知接口,只要在程序里实现相关接口,就可以获取该aware相关的信息 BeanNameAwar...

  • Spring Aware容器感知技术

    ​ Spring Aware是什么 Spring提供Aware接口能让Bean感知Spring容器的存在,即让Be...

  • spring的aware们

    Aware是什么 spring框架提供了多个*Aware接口,用于辅助Spring Bean编程访问Spring容...

  • org.springframework.beans.factor

    Aware 的含义 察觉、注意到、知道的。 Aware 接口文档 一个标记父接口,指示了一个 Bean 有资格被 ...

网友评论

      本文标题:Aware接口

      本文链接:https://www.haomeiwen.com/subject/vfdnzqtx.html