Aware注入Spring底层组件&原理

35 篇文章 11 订阅

1、Aware接口

  • Aware 接口,提供了类似回调函数的功能;
  • 我们声明的Bean想要使用Spring 容器底层的一些组件(Application Context,Bean Factory)需要实现xxxAware接口,在创建对象的时候,会调用接口规定的方法注入相关组件;

Aware接口定义:一个标记超接口,表明一个 bean 有资格被特定框架对象的 Spring 容器通过回调样式的方法。实际的方法签名由各个子接口决定,但应该通常只包含一个接受单个参数的返回 void 的方法。常见的子接口有: 

//1)ApplicationContextAware 自动注入IOC容器
package org.springframework.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;

public interface ApplicationContextAware extends Aware {
  void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

//2)ApplicationEventPublisherAware 注入事件派发器
package org.springframework.context;
import org.springframework.beans.factory.Aware;

public interface ApplicationEventPublisherAware extends Aware {
  void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}

//3)BeanClassLoaderAware 类加载器
package org.springframework.beans.factory;

public interface BeanClassLoaderAware extends Aware {
  void setBeanClassLoader(ClassLoader classLoader);
}

//4)BeanFactoryAware Bean工厂
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;

public interface BeanFactoryAware extends Aware {
  void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

//5)BeanNameAware Bean名字
package org.springframework.beans.factory;

public interface BeanNameAware extends Aware {
  void setBeanName(String name);
}

//6)EmbeddedValueResolverAware Embedded值解析器
package org.springframework.context;
import org.springframework.beans.factory.Aware;
import org.springframework.util.StringValueResolver;

public interface EmbeddedValueResolverAware extends Aware {
  void setEmbeddedValueResolver(StringValueResolver resolver);
}

//7)EnvironmentAware 环境
package org.springframework.context;
import org.springframework.beans.factory.Aware;
import org.springframework.core.env.Environment;

public interface EnvironmentAware extends Aware {
  void setEnvironment(Environment environment);
}

//8)ImportAware 导入相关的
package org.springframework.context.annotation;
import org.springframework.beans.factory.Aware;
import org.springframework.core.type.AnnotationMetadata;

public interface ImportAware extends Aware {
  void setImportMetadata(AnnotationMetadata importMetadata);
}

//9)LoadTimeWeaverAware 导入相关的
package org.springframework.context.weaving;
import org.springframework.beans.factory.Aware;
import org.springframework.instrument.classloading.LoadTimeWeaver;

public interface LoadTimeWeaverAware extends Aware {
  void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver);
}

//10)MessageSourceAware 国际化
package org.springframework.context;
import org.springframework.beans.factory.Aware;

public interface MessageSourceAware extends Aware {
  void setMessageSource(MessageSource messageSource);
}

//11)NotificationPublisherAware 发送通知的支持
package org.springframework.jmx.export.notification;
import org.springframework.beans.factory.Aware;

public interface NotificationPublisherAware extends Aware {
  void setNotificationPublisher(NotificationPublisher notificationPublisher);
}

//12)ResourceLoaderAware 资源加载器
package org.springframework.context;
import org.springframework.beans.factory.Aware;
import org.springframework.core.io.ResourceLoader;

public interface ResourceLoaderAware extends Aware {
  void setResourceLoader(ResourceLoader resourceLoader);

}

示例:

package com.hw.springannotation.beans;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;

@Component
public class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {
    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("传入的IOC " + applicationContext);
        this.applicationContext = applicationContext;
    }

    public void setBeanName(String name) {
        System.out.println("当前bean的名字" + name);
    }

    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String value = resolver.resolveStringValue("你好${os.name} 我是#{20*20}");
        System.out.println("解析的字符串:" + value);
    }
}

2、ApplicationContextAware原理

ApplicationContextAware可以说是spring框架中对BeanPostProcessor的一个应用,还包括一些其他的Aware,如BeanFactoryAware、ResourceLoaderAware、ServletContextAware等等。

我们先来看一段代码:

@Component
public class SpringContextUtil implements ApplicationContextAware {

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

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return applicationContext.getBean(name, clazz);
    }
}

利用这个工具类,就可以在代码任意地方获取spring bean实例。其本质是通过ApplicationContext的getBean方法来获取的,那么这个工具类是如何注入ApplicationContext对象的呢?

源码分析:

通过AbstractApplicationContext的refresh方法入口:

 prepareBeanFactory方法:

ApplicationContextAwareProcessor实现了BeanPostProcessor接口,构造时传入ApplicationContext类型参数。实现BeanPostProcessor接口的postProcessBeforeInitialization方法 -> invokeAwareInterfaces

我们都知道:实现了BeanPostProcessor接口,可以在bean初始化前、后根据自己业务做一些事情(见:spring BeanPostProcessor处理器原理_赶路人儿-CSDN博客);可以看到postProcessBeforeInitialization方法里面,调用invokeAwareInterfaces方法,会根据不同的Aware来设置不同属性。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值