• Aware接口


    这个是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;
        }
    }
    

    本文转自:https://www.jianshu.com/p/72da0fe51dc7

  • 相关阅读:
    Bootstrap(项目2)
    Bootstrap(项目1)
    Bootstrap(Carousel幻灯片)轮播图
    Bootstrap(滚动监听)
    Bootstrap基础10(标签页)
    Bootstrap基础9(工具提示框、警告框、弹出框)
    Bootstrap基础8(模态框(弹窗))
    Bootstrap基础7(标签、徽章、大屏展播、页面标题、缩略图、进度条、面板、折叠效果)
    Bootstrap基础6(路径导航)
    2018~2019学年下学期《计算机图像处理》
  • 原文地址:https://www.cnblogs.com/snake107/p/12103241.html
Copyright © 2020-2023  润新知