宣传网站制作,益阳网站建设,国际域名注册查询,凡科网站建设视频一、概述 Spring IOC容器的扩展点是指在IOC加载的过程中#xff0c;如何对即将要创建的bean进行扩展。 二、扩展点
2.1、BeanDefinitionRegistryPostProcessor
2.1.1、概述 BeanDefinitionRegistryPostProcessor是bean定义的后置处理器#xff0c;在BeanDefinition加载后如何对即将要创建的bean进行扩展。 二、扩展点
2.1、BeanDefinitionRegistryPostProcessor
2.1.1、概述 BeanDefinitionRegistryPostProcessor是bean定义的后置处理器在BeanDefinition加载后实例化bean之前调用 invokeBeanFactoryPostProcessors时进行扩展通过改变BeanDefinition的定义信息进行扩展源码如下 2.1.2、继承结构 2.1.3、案例
2.1.3.1、ATM
/*** Author : 一叶浮萍归大海* Date: 2023/11/23 15:06* Description:*/
Slf4j
Component(value atm)
public class ATM {public int withdrawMoney(int money) {log.info(取钱方法正在执行...);if (money 100) {throw new RuntimeException(自定义的异常);}return money;}}
2.1.3.2、MySpringConfig
/*** Author : 一叶浮萍归大海* Date: 2023/11/23 15:29* Description:*/
Configuration
ComponentScan(basePackages {org.star})
public class MySpringConfig {} 2.1.3.3、MyBeanDefinitionRegistryPostProcessor
/*** Author : 一叶浮萍归大海* Date: 2023/11/25 17:38* Description:*/
Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {/*** 作用动态注册BeanDefinition* 调用时机IOC加载时注册BeanDefinition的时候会调用* param registry the bean definition registry used by the application context* throws BeansException*/Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {RootBeanDefinition definition new RootBeanDefinition(ATM.class);// 设置ATM bean为多实例definition.setScope(prototype);registry.registerBeanDefinition(atm,definition);}Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition beanFactory.getBeanDefinition(atm);// 将atm设置为懒加载这样在容器启动时将不会创建bean只有在getBean时才会创建对象beanDefinition.setLazyInit(true);}
}2.1.3.4、AopFullAnnotationMainApp
/*** Author : 一叶浮萍归大海* Date: 2023/11/23 15:14* Description:*/
Slf4j
public class AopFullAnnotationMainApp {public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(MySpringConfig.class);ATM atm1 context.getBean(atm, ATM.class);ATM atm2 context.getBean(atm, ATM.class);log.info(atm1:{}atm2:{},(atm1 atm2):{}, atm1,atm2,(atm1 atm2));}} 2.2、xxxAware接口
2.2.1、概述 Spring中存在着大量的xxxAware接口实现类用于在bean初始化完成之前做一些前置操作程序员可以自己实现xxxAware接口重写里边的方法修改bean的定义信息进行扩展。 2.2.2、继承结构 2.2.3、案例
2.2.3.1、ATM 同上。 2.2.3.2、MySpringConfig 同上。 2.2.3.3、MyApplicationContextAware
/*** Author : 一叶浮萍归大海* Date: 2023/11/25 18:51* Description:*/
Component
public class MyApplicationContextAware implements ApplicationContextAware {public ApplicationContext applicationContext;Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext applicationContext;AnnotationConfigApplicationContext context (AnnotationConfigApplicationContext) applicationContext;ConfigurableListableBeanFactory beanFactory context.getBeanFactory();BeanDefinition beanDefinition beanFactory.getBeanDefinition(atm);beanDefinition.setScope(prototype);}}
2.2.3.4、AopFullAnnotationMainApp 同上。 2.2.3、调用链路 2.2.4、注意事项 通过观察 2.1.3.4和 2.2.3.4的执行结果不能发现xxxAware接口中配置的扩展覆盖了BeanDefinitionRegistryPostProcessor中的配置说明xxxAware的优先级更高这个也很好理解对于同样的一个bean后边的配置肯定会覆盖掉前边的配置。 2.3、生命周期回调时进行扩展
2.3.1、概述 bean的生命周期回调主要分为两种一种是初始化进行调用另外一种是销毁时进行调用但是不管是初始化还是销毁都对应着三种方式即 a、PostConstruct PreDestroy b、实现接口 InitializingBean, DisposableBean的方式 c、Bean(initMethod init,destroyMethod destroy)的方式 2.4、初始化后实例化前进行扩展
2.4.1、bean创建完成的标识 当循环完所有的DeanDefinition后bean就创建完了。 2.4.2、大致流程 启动IOC容器 refresh() finishBeanFactoryInitialization(beanFactory)beanFactory.preInstantiateSingletons() 2.4.3、源码解析
#1、启动IOC容器
AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(MySpringConfig.class);#2、refresh()
public AnnotationConfigApplicationContext(Class?... componentClasses) {this();register(componentClasses);refresh();
}# 3、finishBeanFactoryInitialization(beanFactory)
Override
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();// Prepare the bean factory for use in this context.prepareBeanFactory(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);// Register bean processors that intercept bean creation.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.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn(Exception encountered during context initialization - cancelling refresh attempt: ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset active flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Springs core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}
}# 4、beanFactory.preInstantiateSingletons();
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(strVal - 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.beanFactory.preInstantiateSingletons();
}# 5、beanFactory.preInstantiateSingletons();
Override
public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace(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.ListString 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)) {Object bean getBean(FACTORY_BEAN_PREFIX beanName);if (bean instanceof FactoryBean) {final FactoryBean? factory (FactoryBean?) bean;boolean isEagerInit;if (System.getSecurityManager() ! null factory instanceof SmartFactoryBean) {isEagerInit AccessController.doPrivileged((PrivilegedActionBoolean)((SmartFactoryBean?) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit (factory instanceof SmartFactoryBean ((SmartFactoryBean?) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {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((PrivilegedActionObject) () - {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}
}
2.4.4、通过监听器扩展
2.4.4.1、Computer
/*** Author : 一叶浮萍归大海* Date: 2023/11/27 11:52* Description:*/
Getter
Setter
Accessors(chain true)
Component
public class Computer {/*** 电脑名称*/private String name;/*** 品牌*/private String brand;}
2.4.4.2、 MyContextRefreshedEvent
/*** Author : 一叶浮萍归大海* Date: 2023/11/27 11:48* Description: 监听器*/
Component
public class MyContextRefreshedEvent {EventListener(ContextRefreshedEvent.class)public void onContextRefreshedEvent(ContextRefreshedEvent event) {System.out.println(event);// bean初始化完成后做扩展扩展代码写在这里ConfigurableApplicationContext context (ConfigurableApplicationContext) event.getApplicationContext();DefaultListableBeanFactory factory (DefaultListableBeanFactory) context.getBeanFactory();BeanDefinition beanDefinition factory.getBeanDefinition(computer);beanDefinition.setScope(prototype);factory.registerBeanDefinition(computer,beanDefinition);System.out.println(all singleton beans loaded,onContextRefreshedEvent execute success!);}}
2.4.4.3、MySpringConfig同上
2.4.4.4、AopFullAnnotationMainApp
Slf4j
public class AopFullAnnotationMainApp {public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(MySpringConfig.class);Computer computer1 context.getBean(Computer.class);Computer computer2 context.getBean(Computer.class);log.info(computer1:{},computer2:{},(computer1 computer2 ?) : {},computer1,computer2,(computer1 computer2));}
} 2.4.5、通过接口扩展
2.4.5.1、Computer
/*** Author : 一叶浮萍归大海* Date: 2023/11/27 11:52* Description:*/
Getter
Setter
Accessors(chain true)
Component
Slf4j
public class Computer {/*** 电脑名称*/private String name;/*** 品牌*/private String brand;public void init() {Computer computer new Computer().setName(OptiPlex7010MT Plus13).setBrand(戴尔);log.info(Computers init was invoked! computer:{}, JSON.toJSONString(computer));}}
2.4.5.2、MySmartInitializingSingleton
/*** Author : 一叶浮萍归大海* Date: 2023/11/27 13:04* Description:*/
Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {Resourceprivate ApplicationContext applicationContext;Overridepublic void afterSingletonsInstantiated() {ConfigurableApplicationContext context (ConfigurableApplicationContext) applicationContext;DefaultListableBeanFactory factory (DefaultListableBeanFactory) context.getBeanFactory();BeanDefinition beanDefinition factory.getBeanDefinition(computer);beanDefinition.setInitMethodName(init);beanDefinition.setScope(prototype);factory.registerBeanDefinition(computer,beanDefinition);System.out.println(all singleton beans loaded,afterSingletonsInstantiated execute success!);}
}
2.4.5.3、MySpringConfig同上
2.4.5.4、AopFullAnnotationMainApp同上