springboot中 ApplicationContextAwareProcessor 及 ignoreDependencyInterface方法的解读

  • ApplicationContextAwareProcessor 用于在创建bean时的前置操作
    其中只有两个方法
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

		// 判断了传进来的bean是否实现了if里面那堆接口。如果没有。则直接返回 true
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
			return bean;
		}

		...
		// 调用了另一个方法,将bean传入
		invokeAwareInterfaces(bean);
		...

		return bean;
	}
	
	// 这几个if判断的接口中。都默认有set + 自身类名 的方法。
	// 为什么这么做?因为为了保证了set进去的bean的准确性。交给框架直接赋值。
	// 可以说是取消了以下接口的依赖。这样一来。还需要声明取消依赖。所以引入了ignoreDependencyInterface方法
	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		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);
		}
	}
  • ignoreDependencyInterface 是BeanFactory的方法,用来忽略接口的特殊依赖。怎么个特殊法?先来看看这个方法在springboot中的位置。

AbstractApplicationContext.class

在这里插入图片描述
添加了ApplicationContextAwareProcessor后就开始忽略那6个类
ignoreDependencyInterface()将入参放入ignoredDependencyInterfaces中

private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();

用来之后AutowireUtils中被调用

AutowireUtils.class

// 这个方法应该就是判断一个类是否有实现了interfaces接口。并且interfaces接口必须有set开头的方法。
public static boolean isSetterDefinedInInterface(PropertyDescriptor pd, Set<Class<?>> interfaces) {
		// 待判断的类的set方法
		Method setter = pd.getWriteMethod();
		if (setter != null) {
			// 获取类类型
			Class<?> targetClass = setter.getDeclaringClass();
			for (Class<?> ifc : interfaces) {
				// 如果实现了interfaces中的接口 并且 interfaces中的接口也有同名的set接口的方法
				if (ifc.isAssignableFrom(targetClass) && ClassUtils.hasMethod(ifc, setter)) {
					return true;
				}
			}
		}
		return false;
	}
  • 举个例子就是 ApplicationContextAware接口,用于直接返回 上下文
// 因为springboot启动时忽略了ApplicationContextAware.class。所以是不会依赖注入。而是交给了框架“注入”。
// 对外其实是无感知。或是叫透明
@Component
public class GetApplicationContextAware implements ApplicationContextAware {

    private ApplicationContext applicationContext;

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

    public ApplicationContext getApplicationContext(){
        return this.applicationContext;
    }
}

关于ignoreDependencyInterface方法的使用场景可以参考:https://www.jianshu.com/p/3c7e0608ff1f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值