Spring扩展原理

Spring扩展原理

  • 6 Spring扩展原理
    • 6.1 BeanFactoryPostProcessor
    • 6.2 BeanDefinitionRegistryPostProcessor
    • 6.3 ApplicationListener
    • 6.4 ApplicationListener原理
    • 6.5 @EventListener | EventListenerMethodProcessor

  

6 Spring扩展原理

6.1 BeanFactoryPostProcessor

   BeanPostProcessor是bean的后置处理器,BeanFactoryPostProcessor是beanFactory的后置处理器:在beanFactory标准初始化之后调用,所有的bean定义已经保存到beanFactory,但是bean的实例还没有创建。

public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

1、配置类

public class Blue {

    public Blue (){
        System.out.println("Construct.......");
    }
}
@ComponentScan("ext")
@Configuration
public class Extconfig {

    @Bean
    public Blue blue(){
        return new Blue();
    }
}

2、自定义BeanFactoryPostProcessor

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor.....");
        int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
        System.out.println("容器中bean的数量" + beanDefinitionCount);
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        Arrays.asList(beanDefinitionNames).forEach(s -> System.out.println(s));
    }
}

3、测试类

public class ExtTest {

    @Test
    public void test1() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);

    }
}

4、结果

MyBeanFactoryPostProcessor.....
容器中bean的数量9
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extconfig
myBeanFactoryPostProcessor
blue
九月 24, 2019 4:56:42 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Construct.......
Disconnected from the target VM, address: '127.0.0.1:52872', transport: 'socket'

Process finished with exit code 0

5、原理

// Invoke factory processors registered as beans in the context.
//在bean初始化之前进行执行
invokeBeanFactoryPostProcessors(beanFactory);
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
//执行剩余processor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

6.2 BeanDefinitionRegistryPostProcessor

  执行时机:在所有的bean定义信息将要被加载,bean实例还未出创建,优先于BeanFactoryPostProcessor执行,可以利用它给容器中额外的添加一些组件

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    /**
     * registry是bean的定义信息的保存中心,以后beanFactory就是按照BeanDefinitionRegistry里
     * 保存的每一个bean定义信息创建bean创建bean实例
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("容器中bean的数量1:" + registry.getBeanDefinitionCount());
        //第一种方式
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Person.class);
        //第二种方式
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
        registry.registerBeanDefinition("hello", beanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("容器中bean的数量2:"+ beanFactory.getBeanDefinitionCount());
    }
}
容器中bean的数量1:10
容器中bean的数量2:11
MyBeanFactoryPostProcessor.....
容器中bean的数量11
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extconfig
myBeanDefinitionRegistryPostProcessor
myBeanFactoryPostProcessor
blue
hello
九月 24, 2019 9:34:07 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Construct.......
Construct.......

Process finished with exit code 0

原理
1、IOC容器创建
2、refresh()

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

3、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件
   1)依次触发postProcessBeanDefinitionRegistry()方法
   2)再依次触发postProcessBeanFactory()方法
4、从容器中获取到所有的BeanFactoryPostProcessor组件
   依次触发postProcessBeanFactory()方法

6.3 ApplicationListener

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

	/**
	 * Handle an application event.
	 * @param event the event to respond to
	 */
	void onApplicationEvent(E event);
}

监听ApplicationListener及其下面的子事件

public class ExtTest {

    @Test
    public void test1() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);
        applicationContext.close();
    }
}
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("监听到事件"+event);
    }
}
容器中bean的数量1:11
容器中bean的数量2:12
MyBeanFactoryPostProcessor.....
容器中bean的数量12
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extconfig
myApplicationListener
myBeanDefinitionRegistryPostProcessor
myBeanFactoryPostProcessor
blue
hello
九月 24, 2019 9:53:23 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor 
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Construct.......
Construct.......
监听到事件org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2280cdac: startup date [Tue Sep 24 21:53:22 CST 2019]; root of context hierarchy]
九月 24, 2019 9:53:23 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2280cdac: startup date [Tue Sep 24 21:53:22 CST 2019]; root of context hierarchy
监听到事件org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2280cdac: startup date [Tue Sep 24 21:53:22 CST 2019]; root of context hierarchy]

步骤:
1、写一个监听器来监听某个事件,这个事件必须是ApplicationEvent的子类
2、将监听器放入容器中
3、只要容器中有相关事件的发布,我们就能监听到这个事件
  ContextRefreshedEvent:容器刷新完成,所有bean都完全创建完成
  ContextClosedEvent:容器关闭事件
4、发布一个事件

 @Test
    public void test1() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Extconfig.class);

        applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
        });
        applicationContext.close();
    }

Spring扩展原理_第1张图片

6.4 ApplicationListener原理

1、端点运行
Spring扩展原理_第2张图片
2、容器对象创建,refresh();
3、容器刷新完成会发布ContextRefreshedEvent

// Last step: publish corresponding event.
finishRefresh();

4、发布事件

protected void finishRefresh() {
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		//发布事件
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

5、获取事件的多播器(派发器)

getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);

6、拿到所有的ApplicationLinstner

@Override
	public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				//executor :支持异步派发
				executor.execute(new Runnable() {
					@Override
					public void run() {
						invokeListener(listener, event);
					}
				});
			}
			else {
				//同步的方式执行onApplicationEvent()方法
				invokeListener(listener, event);
			}
		}
	}

7、自己发布的事件是执行一样的流程
8、容器关闭会自动发布关闭事件

try {
	// Publish shutdown event.
	publishEvent(new ContextClosedEvent(this));
}

事件的多播器是怎样拿到的
1、初始化多播器方法

// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//在bean初始化之前进行执行
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//bean初始化前后进行
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				//初始化多播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				//注册监听器
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				//加载剩余的单实例bean
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//发布事件
				finishRefresh();

2、先看容器中有没有这个组件,没有的话注册一个,并加入到容器中,就可以在其他组件要派发事件的时候自动注入这个ApplicationEventMulticaster

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 + "]");
			}
		}
	}

3、容器中有哪些监听器
将所有ApplicationListener类型的组件加入到派发器中

protected void registerListeners() {
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

3、可以自定义派发器件、传入AsyncTaskExecutorSyncTaskExecutor支持异步或者同步

6.5 @EventListener | EventListenerMethodProcessor

使用普通的组件也能监听到事件

@Service
public class UserService {

    @EventListener(classes = {ApplicationEvent.class})
    public void listen(ApplicationEvent event){
        System.out.println("UserService监听到的事件"+ event);
    }
}

原理:

 * @author Stephane Nicoll
 * @since 4.2
 * @see EventListenerMethodProcessor
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
	.....
}

由此可见这个注解是在EventListenerMethodProcessor这个后置处理器来处理方法上的EventListener注解

class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware 
public interface SmartInitializingSingleton {

	/**
	 * Invoked right at the end of the singleton pre-instantiation phase,
	 * with a guarantee that all regular singleton beans have been created
	 * already. {@link ListableBeanFactory#getBeansOfType} calls within
	 * this method won't trigger accidental side effects during bootstrap.
	 * 

NOTE: This callback won't be triggered for singleton beans * lazily initialized on demand after {@link BeanFactory} bootstrap, * and not for any other bean scope either. Carefully use it for beans * with the intended bootstrap semantics only. */ void afterSingletonsInstantiated(); }

在EventListenerMethodProcessor对该方法的实现处打断点

refresh();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   	// Initialize conversion service for this context.
   	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
   			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
   		beanFactory.setConversionService(
   				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   	}

   	// Register a default embedded value resolver if no bean post-processor
   	// (such as a PropertyPlaceholderConfigurer bean) registered any before:
   	// at this point, primarily for resolution in annotation attribute values.
   	if (!beanFactory.hasEmbeddedValueResolver()) {
   		beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
   			@Override
   			public String resolveStringValue(String strVal) {
   				return getEnvironment().resolvePlaceholders(strVal);
   			}
   		});
   	}

   	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   	for (String weaverAwareName : weaverAwareNames) {
   		getBean(weaverAwareName);
   	}

   	// Stop using the temporary ClassLoader for type matching.
   	beanFactory.setTempClassLoader(null);

   	// Allow for caching all bean definition metadata, not expecting further changes.
   	beanFactory.freezeConfiguration();

   	// Instantiate all remaining (non-lazy-init) singletons.
   	//初始化所有的单实例bean
   	beanFactory.preInstantiateSingletons();
   }
@Override
   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<String>(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(new PrivilegedAction<Boolean>() {
   						@Override
   						public Boolean run() {
   							return ((SmartFactoryBean<?>) factory).isEagerInit();
   						}
   					}, getAccessControlContext());
   				}
   				else {
   					isEagerInit = (factory instanceof SmartFactoryBean &&
   							((SmartFactoryBean<?>) factory).isEagerInit());
   				}
   				if (isEagerInit) {
   					getBean(beanName);
   				}
   			}
   			else {
   				//实例化bean
   				getBean(beanName);
   			}
   		}
   	}

   	// Trigger post-initialization callback for all applicable beans...
   	for (String beanName : beanNames) {
   		Object singletonInstance = getSingleton(beanName);
   		if (singletonInstance instanceof SmartInitializingSingleton) {
   			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
   			if (System.getSecurityManager() != null) {
   				AccessController.doPrivileged(new PrivilegedAction<Object>() {
   					@Override
   					public Object run() {
   						smartSingleton.afterSingletonsInstantiated();
   						return null;
   					}
   				}, getAccessControlContext());
   			}
   			else {
   				smartSingleton.afterSingletonsInstantiated();
   			}
   		}
   	}
   }

你可能感兴趣的:(SpringSource)