1:接口
接口为org.springframework.beans.factory.Aware
,源码如下:
org.springframework.beans.factory.Aware
public interface Aware {
}
这是一个标记接口,表达的含义是当前bean具备了被告知某些信息的资格,但是具体告知什么,就是具体的子接口来定义了,比如org.springframework.beans.factory.BeanNameAware
代表具备了被告知自己的名称的资格,此时需要来告知bean自己的名字是什么,比如org.springframework.beans.factory.BeanFactoryAware
代表bean具备了被告知自己所在bean工厂容器对象的资格,此时需要告知bean工厂信息,但是仅仅是实现了告知具体信息的Aware接口并不会自动执行告知,这个告知的过程需要通过编码来完成,比如BeanNameAware
,BeanFactoryAware
就是在spring bean执行initializeBean方法时通过如下代码完成的:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
除了这种固定方式,还可以通过BeanPostProcessor
来实现。
2:子类
2.1:子类
只是拿几个子类来说明,其子类是非常非常多的。
- BeanClassLoaderAware
org.springframework.beans.factory.BeanClassLoaderAware
public interface BeanClassLoaderAware extends Aware {
// 回调提供加载类的ClassLoader信息
// 调用的时机是,填充bean属性(即调用populateBean方法)后
//,执行InitializingBean#afterPropertiesSet和init-method前
void setBeanClassLoader(ClassLoader classLoader);
}
- BeanFactoryAware
org.springframework.beans.factory.BeanFactoryAware
public interface BeanFactoryAware extends Aware {
// 会调用提供拥有bean实例的工厂IOC容器,调用的时机是:
// 在调用方法populateBean填充bean属性之后,
// 调用方法InitializingBean#afterPropertiesSet,init-method前
// 传入的参数beanFactory肯定是直接可用的,绝对不会为null
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
- BeanNameAware
org.springframework.beans.factory.BeanNameAware
// 想要从bean工厂容器中获取自己的bean名称,可以实现该接口
// ,但是注意不要依赖与bean名称来执行或者是控制业务逻辑
// 因为bean名称是依赖于外部配置的,而外部配置是随时可能改变的
public interface BeanNameAware extends Aware {
// 设置bean所在的bean工厂中的bean名称,执行时机是:
// 设置bean属性之后,执行InitializingBean#afterPropertiesSet,
// 和init-method方法之前
void setBeanName(String name);
}
- ApplicationContextAware
org.springframework.context.ApplicationContextAware
public interface ApplicationContextAware extends Aware {
/**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
// 设置bean所在的应用程序上下文对象,调用时机是:
// 执行populateBean方法填充bean属性后,
// 执行InitializingBean#afterPropertieSet,init-method方法前
// 执行ResourceLoaderAware#setResourceLoader前,
// 执行ApplicationEventPublisherAware#setApplicationContextEventPublisher前
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
2.2:例子
- 类
public class TestAware implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, BeanClassLoaderAware {
private ClassLoader classLoader;
private BeanFactory beanFactory;
private String name;
private ApplicationContext applicationContext;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
System.out.println("TestAware.setBeanClassLoader");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("TestAware.setBeanFactory");
}
@Override
public void setBeanName(String name) {
this.name = name;
System.out.println("TestAware.setBeanName, name is: " + this.name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("TestAware.setApplicationContext");
}
public void display(){
System.out.println("beanName:" + name);
System.out.println("是否为单例:" + beanFactory.isSingleton(name));
Environment environment = applicationContext.getEnvironment();
System.setProperty("spring.active.profiles", "online");
String activeProfiles = environment.getProperty("spring.active.profiles");
System.out.println(activeProfiles);
}
}
- 测试
@Test
public void testaware() {
ClassPathXmlApplicationContext ac
= new ClassPathXmlApplicationContext("testaware.xml");
TestAware testAware = ac.getBean("testAware", TestAware.class);
testAware.display();
}
- 运行
TestAware.setBeanName, name is: testAware
TestAware.setBeanClassLoader
TestAware.setBeanFactory
TestAware.setApplicationContext
beanName:testAware
是否为单例:true
online