前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring中的Aware解析

Spring中的Aware解析

作者头像
爱撒谎的男孩
修改2019-12-31 11:39:41
9630
修改2019-12-31 11:39:41
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏

简介

  • Spring框架中提供了许多实现了Aware接口的类,这些类主要是为了辅助Spring访问容器中的数据,比如BeanNameAware,这个类能够在Spring容器加载的过程中将Bean的名字(id)赋值给变量。

常用的Aware

  • BeanNameAware:能够获取bean的名称,即是id
  • BeanFactoryAware:获取BeanFactory实例
  • ApplicationContextAware:获取ApplicationContext
  • MessageSourceAware:获取MessageSource
  • ResourceLoaderAware:获取ResourceLoader
  • EnvironmentAware:获取Environment

ApplicationContextAware

  • ApplicationContext可以获取容器中的bean,但是必须注入才能使用,当一些类不能注入的时候怎么才能获得bean呢?比如Utils中的类,通常不能直接通过注入直接使用ApplicationContext,此时就需要借助ApplicationContextAware这个接口了。
  • ApplicationContextAware的实现类如下
代码语言:javascript
复制
/**
 * 自定义一个实现类,一定要注入到容器中
 */
@Component
public class ApplicationContextAwareImpl implements ApplicationContextAware {
    /**
     * 容器启动的时候会调用这个方法,只需要将applicationContext设置即可
     * @param applicationContext 容器启动会自动注入
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //将其设置到ApplicationContextUtil
        ApplicationContextUtil.setApplicationContext(applicationContext);
    }
}
  • ApplicationContextUtil如下:
代码语言:javascript
复制
import org.springframework.context.ApplicationContext;
/**
 * ApplicationContext的工具类
 */
public class ApplicationContextUtil {
    /**
     * ApplicationContext对象,会ApplicationContextAwareImpl中的setApplicationContext方法中赋值
     */
    private static ApplicationContext applicationContext;
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    public static void setApplicationContext(ApplicationContext applicationContext) {
        ApplicationContextUtil.applicationContext = applicationContext;
    }
    /**
     * 根据类型获取指定的bean
     * @param requiredType Class
     * @param <T> 泛型
     * @return
     */
    public static <T> T getBean(Class<T> requiredType ){
        return applicationContext.getBean(requiredType);
    }
    /**
     * 根据名称和类型获取Bean
     * @param name bean的id
     * @param requiredType class
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name,Class<T> requiredType){
        return applicationContext.getBean(name,requiredType);
    }
}
  • 配置了如上的工具类,那么就可以直接使用ApplicationContextUtil获取ApplicationContext对象了,而不需要注入了,如下:
代码语言:javascript
复制
	StringRedisTemplate redisTemplate=ApplicationContextUtil.getBean("stringRedisTemplate",StringRedisTemplate.class);

总结

  • spring底层的一些东西并不能通过自动注入直接从ioc容器中获取,但是spring提供了其他的一些方法获取相应的对象,比如一些Aware,要向成功获取指定的对象,必备的条件如下:
    • 实现xxxAware接口
    • 自定义的类注入到容器中

源码解析

  • Aware的装配使用的BeanPostProcessor原理,在初始化之前调用set方法设置对应的值,相应的实现都在org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces,源码如下:
    • 主要的逻辑就是判断相应bean的类型,调用相应的set方法
代码语言:javascript
复制
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 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);
			}
		}
	}

参考文章

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 常用的Aware
  • ApplicationContextAware
  • 总结
  • 源码解析
  • 参考文章
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档