框架扩展必修课-浅谈Spring

前言: 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 对我们开发人员来讲 对于框架的使用会更容易扩展

猜你喜欢

转载自blog.csdn.net/weixin_45657738/article/details/109191681