目录
3.ApplicationContextAwareProcessor中的Aware接口
3.3 EmbeddedValueResolverAware接口
3.5 ApplicationEventPublisherAware接口
本系列一共四篇,其它三篇传送门:
1.ResourceLoader接口
接口源码如下:
public interface ResourceLoader {
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
Resource getResource(String location);
@Nullable
ClassLoader getClassLoader();
}
接口说明:该接口是在spring-core包中,主要的接口方法便是getResource(),功能为传入一个String字符串,具体的内容格式或者特殊符号处理逻辑由用户自定义实现类来处理,Spring实现了一个DefaultResourceLoader,其中实现了Spring默认的资源定位。如果要自定义实现类的话一般而言都是在里面创建一个DefaultResourceLoader,在此基础上进行一些额外的处理。
2.ResourcePatternResolver接口
接口源码如下:
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
}
接口说明:可以看到该接口非常简单,继承了ResourceLoader接口增加了一个getResources()方法,以扩展原来的接口,该接口的使用和ResourceLoader非常相似,对于该接口Spring也有一个实现类PathMatchingResourcePatternResolver,该类内部使用了DefaultResourceLoader类来处理单个的String路径,对于有通配符的路径该类有新的查找处理方式。
3.ApplicationContextAwareProcessor中的Aware接口
接口源码如下:
public interface Aware {
}
接口说明:可以看到这个接口是没有任何方法的,这个接口只是一个标识接口,所有的方法都是由继承接口来声明,接下来大致看几个该接口的子类声明。
3.1 ResourceLoaderAware接口
接口源码如下:
public interface ResourceLoaderAware extends Aware {
void setResourceLoader(ResourceLoader resourceLoader);
}
接口说明:该接口只有一个方法setResourceLoader(),也就是字面意思上的给实现类设置资源加载类resourceLoader,该接口的方法会被Spring容器自动调用,因此如果自定义类需要资源加载器则可以实现该接口从而使Spring自动调用该方法注入resourceLoader。该接口在Spring中的调用代码路径如3.e里面所示。
3.2 EnvironmentAware接口
接口源码如下:
public interface EnvironmentAware extends Aware {
void setEnvironment(Environment environment);
}
接口说明:和其它的Aware子接口一样,当实现类想要获取Spring的Environment对象时,实现该接口便可以获得。在Spring容器中,Environment对象存储了Spring的配置以及系统的配置等信息。其调用链如3.e里面所示。
3.3 EmbeddedValueResolverAware接口
接口源码如下:
public interface EmbeddedValueResolverAware extends Aware {
void setEmbeddedValueResolver(StringValueResolver resolver);
}
接口说明:和其它的Aware子接口类似,当实例化Bean的时候会调用该接口的唯一方法setEmbeddedValueResolver()来将Spring容器管理的StringValueResolver对象赋值给Bean。对象StringValueResolver的作用便是来处理拥有通配符和${}等类似的Expression语言。其调用链如3.e里面所示。
3.4 ApplicationContextAware接口
接口源码如下:
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext)
throws BeansException;
}
接口说明:这个接口在各个Aware接口中应该是用的最多的,某些场景我们需要手动获得Spring的ApplicationContext上下文,我们当然可以使用手动生硬的方式来获取,但Spring容器提供了这个接口来让我们优雅的获得程序上下文。其调用方法链如3.e里面所示。
3.5 ApplicationEventPublisherAware接口
接口源码如下:
public interface ApplicationEventPublisherAware extends Aware {
void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher);
}
接口说明:如果想要使用Spring的事件广播机制而不想自己创建一套,则可以直接在bean中实现该接口,获取Spring的事件广播对象ApplicationEventPublisher。
3.6 Aware接口调用方法链
调用方法链大致源码如下:
public abstract class AbstractApplicationContext
extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public void refresh() throws BeansException, IllegalStateException {
...
// 初始化所有非延迟加载的单例类
finishBeanFactoryInitialization(beanFactory);
...
}
protected void finishBeanFactoryInitialization(
ConfigurableListableBeanFactory beanFactory) {
...
beanFactory.preInstantiateSingletons();
}
}
public class DefaultListableBeanFactory
extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry,
Serializable {
@Override
public void preInstantiateSingletons() throws BeansException {
...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
...
getBean(beanName);
...
}
...
}
}
public abstract class AbstractBeanFactory
extends FactoryBeanRegistrySupport
implements ConfigurableBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name,
@Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly)
throws BeansException {
if (sharedInstance != null && args == null) {
...
} else {
...
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
return createBean(beanName, mbd, args);
}
}
...
}
...
}
public class DefaultSingletonBeanRegistry
extends SimpleAliasRegistry implements SingletonBeanRegistry {
public Object getSingleton(String beanName,
ObjectFactory<?> singletonFactory) {
...
singletonObject = singletonFactory.getObject();
...
}
}
public abstract class AbstractAutowireCapableBeanFactory
extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd,
@Nullable Object[] args) {
...
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
...
}
protected Object doCreateBean(final String beanName,
final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
...
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
...
}
protected Object initializeBean(final String beanName,
final Object bean, @Nullable RootBeanDefinition mbd) {
...
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean =
applyBeanPostProcessorsBeforeInitialization(wrappedBean,
beanName);
}
...
}
public Object applyBeanPostProcessorsBeforeInitialization(
Object existingBean, String beanName)
throws BeansException {
...
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor
.postProcessBeforeInitialization(result, beanName);
...
}
}
}
class ApplicationContextAwareProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(final Object bean,
String beanName) throws BeansException {
if (acc != null) {
...
} else {
invokeAwareInterfaces(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(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);
}
}
}
}