Aware
容器对 Bean 本身的逻辑基本是无侵入的,所以Bean一般不需要了解容器的状态和直接使用容器;但是有的时候是需要在 Bean 中直接操作 容器,所以需要在 Bean中设定对容器的感知;就要使用 Aware 接口的作用。
当我们的类需要容器提供帮助的时候,就需要告知容器,类能够感知到容器的存在—区别于一般的普通类,需要实现特定类型的 Aware接口。
Aware接口 没有任何方法,只是做标签来使用。所以在 Spring 中起作用的 是继承了 Aware的具体接口;
常见接口如下:
ApplicationContextAware
实现该接口的 Bean 在容器创建这个 Bean 实例的时候,将容器本身的实例作为参数传入,给这个 Bean 实例使用,Bean实例使用成员变量接收后,直接使用这个 ApplicationContext 的实例
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
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
BeanNameAware
将 Bean的名字传入,供实现了这个接口的 Bean 实例使用
public interface BeanNameAware extends Aware {
/**
* Set the name of the bean in the bean factory that created this bean.
* <p>Invoked after population of normal bean properties but before an
* init callback such as {@link InitializingBean#afterPropertiesSet()}
* or a custom init-method.
* @param name the name of the bean in the factory.
* Note that this name is the actual bean name used in the factory, which may
* differ from the originally specified name: in particular for inner bean
* names, the actual bean name might have been made unique through appending
* "#..." suffixes. Use the {@link BeanFactoryUtils#originalBeanName(String)}
* method to extract the original bean name (without suffix), if desired.
*/
void setBeanName(String name);
}
BeanFactoryAware
获取 当前 BeanFactory 的实例,获取容器的服务
public interface BeanFactoryAware extends Aware {
/**
* Callback that supplies the owning factory to a bean instance.
* <p>Invoked after the population of normal bean properties
* but before an initialization callback such as
* {@link InitializingBean#afterPropertiesSet()} or a custom init-method.
* @param beanFactory owning BeanFactory (never {@code null}).
* The bean can immediately call methods on the factory.
* @throws BeansException in case of initialization errors
* @see BeanInitializationException
*/
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
MessageSourceAware
获取 MessageSource 相关的文本信息
public interface MessageSourceAware extends Aware {
/**
* Set the MessageSource that this object runs in.
* <p>Invoked after population of normal bean properties but before an init
* callback like InitializingBean's afterPropertiesSet or a custom init-method.
* Invoked before ApplicationContextAware's setApplicationContext.
* @param messageSource message source to be used by this object
*/
void setMessageSource(MessageSource messageSource);
}
ApplicationEventPublisherAware
获取发布器实例,用来发布事件---事件驱动模型
public interface ApplicationEventPublisherAware extends Aware {
/**
* Set the ApplicationEventPublisher that this object runs in.
* <p>Invoked after population of normal bean properties but before an init
* callback like InitializingBean's afterPropertiesSet or a custom init-method.
* Invoked before ApplicationContextAware's setApplicationContext.
* @param applicationEventPublisher event publisher to be used by this object
*/
void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}
ResourceLoaderAware
获取资源加载器,用于获取外部资源文件
以上具体Aware接口中的 各种 set方法是设置不同的东西,供实现这个接口的 Bean 实例使用,这些 set 方法是 Spring框架会调用的---只要实例实现了相应的接口;告知Spring需要使用什么,然后 Spring会调用set方法进行设置。
注意:实现这些接口的 Bean 必须是容器 管理的 Bean ;这样各种类型的 Aware 才会起作用。
@Controller
public class WelcomeController implements ApplicationContextAware, BeanNameAware {
private String myName;
private ApplicationContext myContainer;
@Autowired
private WelcomeService welcomeService;
public void doRequest() {
welcomeService.sayHello("来自Controller的调用问候");
System.out.println("我是谁:" + myName);
System.out.println("我所在的容器:" + myContainer);
String[] allBeanNames = myContainer.getBeanDefinitionNames();
for (String beanName : allBeanNames) {
System.out.println(beanName);
}
System.out.println("======================");
}
@Override
public void setBeanName(String name) {
this.myName = name;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.myContainer = applicationContext;
}
}
输出如下:
我是谁:welcomeController
我所在的容器:org.springframework.context.annotation.AnnotationConfigApplicationContext@1e80bfe8, started on Tue Jun 30 19:51:29 CST 2020
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
entrance
welcomeController
welcomeDao
customizedBeanDefinitionRegistryPostProcessor
customizedBeanPostProcessor
welcomeServiceImpl
user5
网友评论