Spring之Aware

本文介绍了Spring中的Aware接口,包括BeanNameAware、BeanClassLoaderAware、BeanFactoryAware等9种,详细阐述了它们的作用和使用场景,以及在Spring中何时被调用。此外,还分析了ApplicationContextAwareProcessor在bean初始化过程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Aware概述

Aware是Spring提供的一个标记超接口,它里面什么也没有,它主要重要就是向我们提供一种资源访问的入口标记而已,在spring中内置了9个Aware抽象。今天我们主要就来了解一下这9个Aware以及他们是如何工作的。

package org.springframework.beans.factory;

public interface Aware {
}

Aware内置接口

|--Aware
    |--BeanNameAware
    |--BeanClassLoaderAware
    |--BeanFactoryAware
    |--EnvironmentAware
    |--EmbeddedValueResolverAware
    |--ResourceLoaderAware
    |--ApplicationEventPublisherAware
    |--MessageSourceAware
    |--ApplicationContextAware

BeanNameAware

BeanNameAware是Spring框架中提供的一个接口,用于让一个Bean在容器中意识到自己的Bean名称。通过实现BeanNameAware接口,一个Bean可以在初始化阶段访问到它被分配的名称。这对于那些需要根据自己在应用程序上下文中的名称执行特定操作的Bean非常有用。

package org.springframework.beans.factory;

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

BeanClassLoaderAware

BeanClassLoaderAware是Spring框架中提供的另一个接口。它允许一个Bean意识到用于加载该Bean类的类加载器。通过实现BeanClassLoaderAware接口,一个Bean可以在初始化阶段访问类加载器。这对于需要基于类加载器执行操作的Bean非常有用,比如动态类加载或资源加载。

package org.springframework.beans.factory;

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

BeanFactoryAware

BeanFactoryAware是Spring框架中提供的一个接口。它允许一个Bean意识到创建和管理该Bean的Bean工厂。通过实现BeanFactoryAware接口,一个Bean可以在初始化阶段访问工厂。这对于需要与工厂进行交互的Bean非常有用,例如获取其他Bean或访问配置信息。

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

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

EnvironmentAware

EnvironmentAware是Spring框架中提供的一个接口。它允许一个Bean意识到它所运行的应用程序环境。通过实现EnvironmentAware接口,一个Bean可以在初始化阶段访问环境。这对于需要访问特定于环境的信息的Bean非常有用,例如属性、配置文件或活动配置文件,以便根据运行时环境自定义它们的行为。

package org.springframework.context;

import org.springframework.beans.factory.Aware;
import org.springframework.core.env.Environment;

/**
 * Interface to be implemented by any bean that wishes to be notified
 * of the {@link Environment} that it runs in.
 *
 * @author Chris Beams
 * @since 3.1
 */
public interface EnvironmentAware extends Aware {

	/**
	 * Set the {@code Environment} that this object runs in.
	 */
	void setEnvironment(Environment environment);

}


EmbeddedValueResolverAware

EmbeddedValueResolverAware是Spring框架中提供的一个接口。它允许一个Bean意识到用于解析bean定义中占位符和表达式的嵌入式值解析器。通过实现EmbeddedValueResolverAware接口,一个Bean可以在初始化阶段访问值解析器。这对于需要根据运行时值解析属性或配置中的占位符或表达式的Bean非常有用。

package org.springframework.context;

import org.springframework.beans.factory.Aware;
import org.springframework.util.StringValueResolver;

/**
 * Interface to be implemented by any object that wishes to be notified of a
 * <b>StringValueResolver</b> for the <b> resolution of embedded definition values.
 *
 * <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
 * ApplicationContextAware/BeanFactoryAware interfaces.
 *
 * @author Juergen Hoeller
 * @author Chris Beams
 * @since 3.0.3
 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
 */
public interface EmbeddedValueResolverAware extends Aware {

	/**
	 * Set the StringValueResolver to use for resolving embedded definition values.
	 */
	void setEmbeddedValueResolver(StringValueResolver resolver);

}


ResourceLoaderAware

ResourceLoaderAware是Spring框架中提供的一个接口。它允许一个Bean意识到资源加载器,用于加载外部资源文件。通过实现ResourceLoaderAware接口,一个Bean可以在初始化阶段访问资源加载器。这对于需要加载外部资源文件的Bean非常有用,例如配置文件、模板文件等。

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);

}


ApplicationEventPublisherAware

ApplicationEventPublisherAware是Spring框架中提供的一个接口。它允许一个Bean意识到应用事件发布器。通过实现ApplicationEventPublisherAware接口,一个Bean可以在初始化阶段访问事件发布器。这对于需要发布应用事件或与Spring中的事件系统进行交互的Bean非常有用。

package org.springframework.context;

import org.springframework.beans.factory.Aware;


public interface ApplicationEventPublisherAware extends Aware {

	void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);

}


MessageSourceAware

MessageSourceAware是Spring框架中提供的一个接口。它允许一个Bean意识到消息源,消息源负责解析本地化消息。通过实现MessageSourceAware接口,一个Bean可以在初始化阶段访问消息源。这对于需要获取本地化消息或根据不同的语言环境执行消息解析的Bean非常有用。

package org.springframework.context;

import org.springframework.beans.factory.Aware;

public interface MessageSourceAware extends Aware {

	void setMessageSource(MessageSource messageSource);

}


ApplicationContextAware

ApplicationContextAware是Spring框架中提供的一个接口。它允许一个Bean意识到应用程序上下文,也就是Spring容器。通过实现ApplicationContextAware接口,一个Bean可以在初始化阶段访问应用程序上下文。这对于需要与容器进行交互或获取其他Bean的Bean非常有用。

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;

}

Aware在Spring中的调用时机

首先9类Aware在Spring中分成了2类,BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三个为一组在初始化前直接调用,其余6个为一组通过ApplicationContextAwareProcessor后置处理器,在初始化后间接回调。通过Spring创建bean代码跟中我们找到初始化方法。

invokeAwareMethods

在invokeAwareMethods中根据创建bean对象继承接口进行对应资源的植入

    private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            if (bean instanceof BeanClassLoaderAware) {
                ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
            }

            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }

applyBeanPostProcessorsBeforeInitialization

这里是后置处理器BeanPostProcessor统一调用入口,当然这也包括ApplicationContextAwareProcessor后置处理器

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator i$ = this.getBeanPostProcessors().iterator();

        do {
            if (!i$.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)i$.next();
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        } while(result != null);

        return result;
    }

ApplicationContextAwareProcessor

便于阅读理解只保留了相关方法内容,首先我们很容易发现它是实现了后置处理器接口BeanPostProcessor,并实现了方法postProcessBeforeInitialization。所以才有上面我们说得它在bean的初始化方法前调用。

package org.springframework.context.support;


class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}


	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() {
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	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);
			}
		}
	}

}

ApplicationContextAwareProcessor又在哪示例化的呢?

在日常开发过程中文我们也没有对ApplicationContextAwareProcessor进行实例化,它是在什么时候进入到Spring容器中的呢?思考两分钟我们揭秘

AbstractApplicationContext.refresh刷新容器的时候,有个叫prepareBeanFactory的方法执行一些bean工厂的准备工作,在里面

在这里我们找到了Spring容器中添加ApplicationContextAwareProcessor后置处理器的入口

总结

到目前为止我们了解9中Spring内置Aware接口,并且他们分两种方式在bean初始化之前被调用。聪明的小伙伴一定和我一样有个疑问,明明两种方式都能达到目的,为什么不用一个?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值