框架扩展必修课-浅谈Spring

it2023-11-11  62

前言: Spring版本为5.2.9 IDEA创建一个springboot项目,因为现在主要的bean声明,我们都使用了annotation,所以我们使用AnnotationConfigApplicationContext为例.

1.3.06推断构造函数 1.3.09属性填充待补充 详细步骤

1. AnnotationConfigApplicationContext关系图

AnnotationConfigApplicationContext 继承了ApplicationContext接口,拥有事件监听器、BeanFactoryPostProcessor、设置Environment,获取ConfigurableListableBeanFactory等功能 几个重要的功能: 1.11 BeanDefinition 解析class文件 保存class文件的元信息 直接ASM解析 不会JVM加载class 1.12 ListableBeanFactory bean工厂 存储bean applicationContext的getBean就这个类取数据 1.13 ResourceLoader 资源加载 获取resource下资源文件 1.14 EnvironmentCapable 获取当前运行环境的配置文件信息 map存储

1.2 spring启动后的流程

// 1.2.1 创建application AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext("com.example.springtest.service"); // 源码如下 public AnnotationConfigApplicationContext(String... basePackages) { // 1.2.2 创建了AnnotatedBeanDefinitionReader和 ClassPathBeanDefinitionScanner 解析class文件 且存到BeanDefinition this(); // 1.2.3 因为传了路径 会调ClassPathBeanDefinitionScanner进行扫描 // Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);通过路径查询到所有resource文件信息 // 判断是否有@Component注解 放入AnnotatedBeanDefinition中 // 单个class解析信息GenericBeanDefinition -> 合并后解析信息(parent这种需要合并)RootBeanDefinition // 再判断@Scope属性 封装到ScopeMetadata中 // 解析类的Lazy, Primary, DependsOn, Role, Description属性 // 存储到Set<BeanDefinitionHolder> 最后放到beanDefinitionMap<beanName, beanDefinition> this.scan(basePackages); this.refresh(); } public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 1.2.4 环境准备以及容器准备 prepareRefresh(); // 1.2.5 刷新bean工厂 获取工厂对象 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 1.2.6 初始化bean工厂 加载必要的bean prepareBeanFactory(beanFactory); try { // 1.2.7 bean工厂的前置器 内置钩子方法 postProcessBeanFactory postProcessBeanFactory(beanFactory); // 1.2.8 实例化和调用所有 BeanFactoryPostProcessor // BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor // 第一步判断beanFactory instanceof BeanDefinitionRegistry 执行postProcessBeanDefinitionRegistry方法 // 第二步就只能属于BeanFactoryPostProcessor类 执行postProcessBeanFactory invokeBeanFactoryPostProcessors(beanFactory); // 1.2.9 注册implements BeanPostProcessor的类 registerBeanPostProcessors(beanFactory); // 1.2.10 加载本地messageSource Bean 否则往上找ApplicationContext initMessageSource(); // 1.2.11 加载本地applicationEventMulticaster Bean否则往使用this.applicationEventMulticaster initApplicationEventMulticaster(); // 1.2.12 初始化特殊bean 空壳方法 onRefresh(); // 1.2.13 收集监听 且 发布 registerListeners(); // 1.2.14 停止相关准备工作 设置冻结标识 并且初始化非lazy bean(下面详细看这里) finishBeanFactoryInitialization(beanFactory); // 1.2.15 清除相关缓存 发布事件 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 Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }

1.3 上面的1.2.14方法包含了create bean的方法 也就是bean的生命周期 单独来看

// 1.3.01 拿出所有beanDefinition List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // 1.3.02 判断是否是类type FactoryBean 且也是SmartFactoryBean且eagerInit=true或者非FactoryBean 执行getBean(beanName) // 1.3.03 如果scope是Singleton单例 开始创建 scope是Prototype原形创建一个新的 // 1.3.04 加载class类 mbd.getBeanClass() // 1.3.05 resolveBeforeInstantiation 如果执行postProcessBeforeInitialization 返回的数据 != null 直接结束创建 // 1.3.06 推断构造方法实例化 大多数情况下 执行无参构造 优先执行@Autowired(required=true)构造函数 多个@Autowired(required=true)会抛异常 多个候选构造函数的话 会根据pv选择构造器 或者getBean时传参数 // 1.3.07 执行 实现了MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法 // 1.3.08 populateBean 执行 实现了InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法 // 1.3.09 属性填充 后文单独详看 // 1.3.10 InstantiationAwareBeanPostProcessor后置处理器 postProcessProperties // 1.3.11 invokeAwareMethods 执行aware set属性 // 1.3.12 BeanPostProcessor处理器postProcessBeforeInitialization // 1.3.13 InitializingBean处理器afterPropertiesSet或者标注的initMethod方法 // 1.3.14 BeanPostProcessor处理器postProcessAfterInitialization

1.4 FactoryBean

@Component public class FactoryBeanTest implements FactoryBean { @Override public Object getObject() throws Exception { return new OrderService(); } @Override public Class<?> getObjectType() { return OrderService.class; } } Object factoryBeanTest = annotationConfigApplicationContext.getBean("factoryBeanTest"); System.out.println(factoryBeanTest); // console 运行结果如下 也就是说beanFactory getBean会调getObject()方法 com.example.springtest.service.OrderService@6105f8a3 // 如果想获取本类getBean传参前面加一个& Object factoryBeanTest = annotationConfigApplicationContext.getBean("&factoryBeanTest"); System.out.println(factoryBeanTest); // console 运行结果如下 com.example.springtest.service.FactoryBeanTest@44ea608c

1.5 测试一下几个重要的PostProcessor

@Component public class TestPostProcess implements InstantiationAwareBeanPostProcessor, BeanDefinitionRegistryPostProcessor, BeanPostProcessor, MergedBeanDefinitionPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("postProcessBeanFactory 扩展点"); } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("userService")) { System.out.println("postProcessBeforeInstantiation 实例化前扩展点"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")) { System.out.println("postProcessBeforeInstantiation 实例化后扩展点"); } return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if (beanName.equals("userService")) { System.out.println("属性设置"); } return null; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")) { System.out.println("postProcessBeforeInitialization 初始化前扩展点"); } return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")) { System.out.println("postProcessAfterInitialization 初始化后扩展点"); } return bean; } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { if (registry.containsBeanDefinition("userService")) { System.out.println("postProcessBeanDefinitionRegistry BeanDefinition后置处理 扩展点"); } } @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanName.equals("userService")) { System.out.println("postProcessMergedBeanDefinition 实例化后"); } } @Override public void resetBeanDefinition(String beanName) { if (beanName.equals("userService")) { System.out.println("resetBeanDefinition 实例化后"); } } }

运行结果如下: 总结: 使用BeanProcessor 对我们开发人员来讲 对于框架的使用会更容易扩展

最新回复(0)