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来设置不同属性。