版权所有:https://my.oschina.net/u/3995125,禁止转载
同样,我们还是以 AnnotationConfigApplicationContext 作为切入点,开始对整体功能进行分析。
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
进入this();
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
先执行父类的初始化方法,创建IOC容器
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
2.进入AnnotatedBeanDefinitionReader方法执行初始化方法创建BeanDefinition读取器
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotationConfigUtils获取所有BeanPostProcessor的Bean,把下面6个对象注入到IOC容器中了
这里用到了CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 、AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME 等几个常量
常量 | 对应的BeanPostProcessor | 对应的注解 |
---|---|---|
CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME | ConfigurationClassPostProcessor | @Configuration |
AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME | AutowiredAnnotationBeanPostProcessor | @AutoWired |
REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME | RequiredAnnotationBeanPostProcessor | @Required |
COMMON_ANNOTATION_PROCESSOR_BEAN_NAME | CommonAnnotationBeanPostProcessor | @javax.annotation.PostConstruct、@javax.annotation.PreDestroy |
等等,还有几个,就不列了。
3.进入ClassPathBeanDefinitionScanner方法创建classPath下扫描器
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//创建BeanDefinition对象
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { //处理 @Condition注解
return;
}
abd.setInstanceSupplier(instanceSupplier); //设置对象是单例模式还是多例模式,默认单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName()); //获取BeanName,设置的化就采用默认值,否则类名第一个字母小写
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //处理Lazy,primary等注解
.....
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//判断对象是否需要代理,不需要直接返回,需要的化,重新创建BeanDefinition加入代理的信息
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); //注册配置类到IOC容器
}
进入 refresh()方法,可以说refresh函数中包括了几乎ApplicationContext中提供的全部功能,而且此函数中逻辑非常清晰明了。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();//准备刷新上下文环境
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//初始化BeanFacgtory
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);//初始化BeanFactory进行各种功能填充
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);//子类覆盖方法做额外的处理
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);//激活各种BeanFactory处理器
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);//注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean的时候
// Initialize message source for this context.
initMessageSource();//为上下文初始化Message源,集不同语言的消息体,国际化处理
// Initialize event multicaster for this context.
initApplicationEventMulticaster();//初始化应用消息广播器,并放入applicationEventMulticaster bean中
// Initialize other special beans in specific context subclasses.
onRefresh();//留给子类来初始化其它的Bean
// Check for listener beans and register them.
registerListeners();//在所有注册的Bean中查找Listener bean,注册到消息广播器中
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//初始化剩下的单实例(非惰性)
// Last step: publish corresponding event.
finishRefresh();//完成刷新过程,通知生命周期处理器 LifecycleProcessor刷新过程,同时发出 ContextRefreshedEvent 通知别人
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();//销毁Bean
// Reset 'active' flag.
cancelRefresh(ex);//更改活跃状态
// Propagate exception to caller.
throw ex;
}
}
}
prepareRefresh();函数主要作用是对系统属性及环境变量的初始化及验证
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
initPropertySources();//留给子类覆盖
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();//验证需要的属性文件是否都已经放入环境中去了
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
initPropertySources是空的,没有任何逻辑处理, 而getEnvironment().validateRequiredProperties()也是因为没有需要验证的属性而没有做任何处理,然而这两个方法作用还是很大的。那么该怎么用呢?
1.initPropertySources正符合Spring的开放式结构设计,给用户最大的扩展Spring的能力。 2.validateRequiredProperties则是对属性进行验证,那么如何验证呢?我们举个例子来说明下:
public class MyAnnotationConfigApplication extends AnnotationConfigApplicationContext {
public MyAnnotationConfigApplication(Class<?>... annotatedClasses){
super(annotatedClasses);
}
@Override
protected void initPropertySources(){
//添加验证要求
getEnvironment().setRequiredProperties("VAR");
}
}
我们自定义了继承自AnnotationConfigApplicationContext的MyAnnotationConfigApplication,并重写了initPropertySources方法,在方法中添加了我们的个性化需求,那么在验证的时候也就是程序走到 validateRequiredProperties()代码的时候,我们还需要替换掉原有的AnnotationConfigApplicationContext为我们自定义的MyAnnotationConfigApplication。
public class Test002 {
public static void main(String[] args) {
ApplicationContext context = new MyAnnotationConfigApplication(MyConfig.class);
Object payEntity = context.getBean("payEntity");
System.out.println(payEntity);
}
}
如果系统并没有检测到对应的VAR环境变量,那么就会抛出异常:
obtainFreshBeanFactory()方法的作用是:经过这个方法,ApplicationContext就已经拥有了BeanFactory的全部功能。
/**
* Tell the subclass to refresh the internal bean factory.
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//初始化BeanFactory
refreshBeanFactory();
//返回当前实体的BeanFactory属性
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
方法中将核心实现委托给了refreshBeanFactory:
/**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();//创建DefaultListableBeanFactory
beanFactory.setSerializationId(getId());//序列化id
customizeBeanFactory(beanFactory);//定制BeanFactory,设置相关属性,是否允许循环依赖,是否允许覆盖
loadBeanDefinitions(beanFactory);//加载BeanDefinition
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//如果属性不为空,则设置给beanFactory对象相应属性,此属性的含义是:是否允许覆盖同名称的不同定义的对象
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//如果属性不为空,设置给beanFactory对象相应的属性,这块属性的含义是:是否允许Bean之间存在循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
对于允许覆盖和允许循环依赖的设置这里只是进行了非空判断,如果不为空的化要进行设置,但是这里没有设置,所以还是那个套路,使用子类覆盖方法。
public class MyAnnotationConfigApplication extends AnnotationConfigApplicationContext {
public MyAnnotationConfigApplication(Class<?>... annotatedClasses){
super(annotatedClasses);
}
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory){
super.setAllowBeanDefinitionOverriding(false);//是否允许覆盖同名称的不同定义的对象
super.setAllowCircularReferences(false);//是否允许Bean之间存在循环依赖
}
}
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);//为指定的beanFactory创建XmlBeanDefinitionReader
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());//对beanDefinitionReader进行环境变量的设置
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);//进行设置可以覆盖
loadBeanDefinitions(beanDefinitionReader);
}
在初始化了DefaultListableBeanFactory和XmlBeanDefinitionReader后就可以进行配置文件的读取了
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
counter += loadBeanDefinitions(resource);
}
return counter;
}
经过此步骤,类型DefaultListableBeanFactory的变量beanFactory已经包含了所有已经解析好的配置
进入函数prepareBeanFactory前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也由此展开。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());//设置BeanFactory的classLoader为当前context的classLoader
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));//设置beanFactory的表达式语言处理器,默认可以使用#{bean.xx}的形式来调用相关的属性值。
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//为BeanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//添加BeanPostProcessor
//设置了几个忽略自定装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//设置了几个自定装配的规则
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 增加了对AspectJ的支持
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 添加了默认的系统环境bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
上面函数中主要进行了几个方面的扩展
上面可扩展功能很多,我就不一一介绍了,下面我们来挑几个我们感兴趣的函数来分析下:
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)),其主要目的就是注册个BeanPostProcessor,而真正的逻辑还是在ApplicationContextAwareProcessor中
ApplicationContextAwareProcessor实现了BeanPostProcessor接口,我们回顾下之前讲解的内容,在Bean实例化的时候,也就是Spring激活Bean的init-method方法前后, 会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。所以我们也就去看看ApplicationContextAwareProcessor对这两个方法的实现。
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
对于后置处理器BeanPostProcessor的后置处理方法中并没有做任何逻辑处理,那么我们转向后置处理器的前置处理
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((PrivilegedAction<Object>) () -> {
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(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);
}
}
}
postProcessBeforeInitialization方法中调用了invokeAwareInterfaces。从invokeAwareInterfaces方法中,我们或许已经差不多知道了Spring的用意,实现了这些Aware接口的Bean在被初始化后,可以取到一些对于的资源。
示例:
@Component
public class MyApplicationContext implements ApplicationContextAware {
/**
* spring底层中为什么能够实现ApplicationContextAware接口 就能够拿到ApplicationContext
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext:>>>>"+applicationContext);
}
}
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
我们自定义MyInstantiationAwareBeanPostProcessor实现BeanPostProcessor 接口
@Component
public class MyInstantiationAwareBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization....");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization....");
return null;
}
}
@Import(MyInstantiationAwareBeanPostProcessor.class)
结果输出:每次初始化一个Bean就会在之前和之后处理一些自定义逻辑
postProcessBeforeInitialization.... 4.bean init方法执行.. postProcessAfterInitialization....
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
进入SimpleApplicationEventMulticaster找到这段代码:
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
....
listener.onApplicationEvent(event);
}
可以推断,当产生Spring事件的时候会默认使用SimpleApplicationEventMulticaster的multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听事件的处理。 而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。
进入registerListeners函数,开始注册监听器:
protected void registerListeners() {
for (ApplicationListener<?> listener : getApplicationListeners()) {//硬编码方式注册的监听器处理
getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);//配置文件注册的监听器处理
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
Application下抽象子类ApplicationContextEvent的下面有4个已经实现好的事件
同样,这四个事件都继承了ApplicationEvent,如果我们想自定义事件,也可以通过继承ApplicationEvent来实现
使用示例:
1.定义监听事件
public class TestEvent extends ApplicationEvent {
private String msg;
public TestEvent(Object source){
super(source);
}
public TestEvent(Object source,String msg){
super(source);
this.msg=msg;
}
public void print(){
System.out.println(msg);
}
}
2.定义监听器
public class TestListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof TestEvent){
TestEvent testEvent= (TestEvent)event;
testEvent.print();
}
}
}
注入容器
@Import(TestListener.class)
测试:
public class Test001 {
public static void main(String[] args) {
/**
* IOC容器初始化单例对象都是循环遍历调用getBean方法
*/
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
TestEvent testEvent = new TestEvent("hello", "hello word");
applicationContext.publishEvent(testEvent);
}
}
输出结果:
我们在补充一个注解形式的例子:
public class TestEvent extends ApplicationEvent {
private String msg;
public TestEvent(Object source){
super(source);
}
public TestEvent(Object source,String msg){
super(source);
this.msg=msg;
}
public void print(){
System.out.println("注册监听器..,TestEvent....");
}
}
@Component
public class MyAnnotationListener {
@EventListener
public String listener1(TestEvent event) {
if (event instanceof TestEvent){
TestEvent testEvent=event;
testEvent.print();
}
return "xd";
}
}
@Import(MyAnnotationListener.class)
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
MyAnnotationListener myAnnotationListener = new MyAnnotationListener();
applicationContext.publishEvent(myAnnotationListener.listener1(new TestEvent("jj")));
输出:
进入finishBeanFactoryInitialization函数初始化所有非懒加载Bean
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(//定义转换器从String转为Date的方式,可以自己扩展,我就不多说了
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();//冻结所有Bean的定义,说明注册的Bean定义将不被修改或处理。
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();//初始化剩下的单实例(非惰性)
}
@Override
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
ApplicationContext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提前实例化的好处是,在配置中任何错误就会立即被发现Z(否则的化,一旦出错,排除bug相当困难)。
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
((SmartFactoryBean<?>) factory).isEagerInit(),
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
在Spring中还提供了Lifecycle接口,Lifecycle接口中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并且在spring关闭的时候调用stop方法来结束生命周期, 通常用来配置后台程序,在启动后一直运行(such as MQ进行轮询等)。
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();//当ApplicationContext启动或者停止时,会通过LifecycleProcessor来与所有声明的bean的周期做状态更新,而在LifecycleProcessor使用前需要初始化
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();//启动所有实现了Lifecycle接口的bean
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));//当完成ApplicationContext初始化的时候,要通过Spring中的事件发布机制来发出ContextRefreshedEvent监听事件,以保证对应的监听器可以做进一步的逻辑处理
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
到这里,我们就谈完了!!!
参考书籍:Spring源码深度解析
版权所有:https://my.oschina.net/u/3995125,禁止转载