spring 扩展功能心得(一)
spring作为现在最火的开发框架,熟练的使用spring和扩展功能,能大大提高开发效率
首先从spring的启动来看,spring启动的核心方法是 refresh 方法,该方法定义在AbstractApplicationContext.class
下面上代码 基于spring4.3.18,基于ClassPathXmlApplicationContext
public void refresh() throws BeansException, IllegalStateException { Object var1 = this.startupShutdownMonitor; synchronized(this.startupShutdownMonitor) { //前置刷新工作,可以进行一些环境变量的校验 this.prepareRefresh(); //生成beanFactory 在生成过程中加载bean定义文件(spring.xml和spring注解等) ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); //bean工厂准备工作 this.prepareBeanFactory(beanFactory); try { //加载postProcessBeanFactory this.postProcessBeanFactory(beanFactory); //调用postProcessBeanFactory,可以对bena工厂的属性以及对某些特定beanDefinition 修改属性 this.invokeBeanFactoryPostProcessors(beanFactory); //注册bean定义处理器,在bean进行初始化时,可以进行前置处理和后置处理 this.registerBeanPostProcessors(beanFactory); //初始化message信息 国际化使用 this.initMessageSource(); //初始化时间转发器 this.initApplicationEventMulticaster(); //模板方法,需要自己自定义 this.onRefresh(); //注册监听器 this.registerListeners(); //实例化bean this.finishBeanFactoryInitialization(beanFactory); //完成bean加载,发送refresh完成事件 this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } }
1 prepareRefresh 刷新前准备事件
可以重写initPropertySources方法,进行环境变量参数以及其他参数校验
demo如下
public class MyContext extends ClassPathXmlApplicationContext { public MyContext(String...configLocations) { super(configLocations); } public MyContext(String[] configLocations,boolean refresh) { super(configLocations,refresh); } protected void initPropertySources(){ getEnvironment().setRequiredProperties("envir"); System.out.println( "envirment envir:"+getEnvironment().getSystemEnvironment().get("envir")); } public static void main(String[] args) { ApplicationContext context = new MyContext("spring.xml"); } }
在spring加载时,getEnvironment().setRequiredProperties() 方法,
在没有“envir” 环境变量时,抛出异常,在项目启动阶段将问题抛出,减少问题排查难度
2obtainFreshBeanFactory 生成beanFactory 加载bean定义文件
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //核心操作,由AbstractRefreshableApplicationContext 进行实现 this.refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); if (this.logger.isDebugEnabled()) { this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory); } return beanFactory; }
AbstractRefreshableApplicationContext.refreshBeanFactory()
protected final void refreshBeanFactory() throws BeansException { //在获取到context后,可以进行手动refresh,在二次refresh时,需要销毁初始化创建的beanFactory if (this.hasBeanFactory()) { //判断是否已经存在了beanFactory this.destroyBeans(); //销毁所有bean对象,释放内存,主要是将存储bean和bean定义的map进行clear操作 this.closeBeanFactory();//关闭beanFactory,将序列化ID置为 null然后将beanFactory置为null } try { //创建beanFactory DefaultListableBeanFactory beanFactory = this.createBeanFactory(); //设置序列化ID 默认为:启动类名+@+启动类对象的hashCode.toHexString beanFactory.setSerializationId(this.getId()); //定义beanFactory 主要是设置是否允许Bean定义覆盖和循环引用(定义覆盖就是同一个名字有多个类,以后面的类为准) this.customizeBeanFactory(beanFactory); //加载bean定义文件,读取.xml文件 this.loadBeanDefinitions(beanFactory); Object var2 = this.beanFactoryMonitor; synchronized(this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException var5) { throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5); } }
关于上面说到的允许Bean定义覆盖 可以参考一下demo 实现一个bean多定义,以后加载的bean为准
到这一步 已经完成了bean信息定义的加载,具体的怎么读取配置文件在此不做解析

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
java线程池使用(二)------部分源码解析
前一篇博客介绍了构造参数分别是什么意思现在介绍java线程池源码1 init线程池初始化,代码比较简单 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || //核心线程数校验 maximumPoolSize <= 0 || //非核心线程数校验 maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) //必...
- 下一篇
京东与人民日报新媒体深入合作,“云+AI”驱动传媒业智能化升级
【51CTO.com原创稿件】 当中国移动互联网月度活跃用户(终端)稳定在十亿之上,媒体行业在移动互联网的布局也逐步成型。同时在5G、人工智能、大数据、云计算、物联网等新技术的推动下,信息生产方式和传播方式也在持续发生深刻变化。 顺应这一趋势,人民日报社一方面坚持移动优先策略,形成了以两微两端为主的移动传播新格局,另一方面也在密切关注媒体技术的革新,推动媒体融合向纵深发展。在亿级的用户体量下,基于云计算实现多端互联,在人工智能等技术的加持下推进质变式融合,成为人民日报社新媒体中心的迫切需求。 在这一背景下,京东云与AI成为人民日报新媒体选择的技术服务合作伙伴。随着京东“云+AI”持续赋能,人民日报新媒体不断完善自身的基因进化,向智慧媒体转型,而京东云与AI也迎来了快速增长的突破点,在To B市场攻坚战中迈向了新的阶段。 换脸H5:“云+AI”提供“有温度”的用户体验 媒体的智能化升级不断丰富着信息的呈现形态和交互场景。AI技术与媒体的结合,使得用户也可以参与到内容的生产和传播中。人民日报新媒体推出的 “换脸”微电影H5就是一个典型应用。 2019年国庆期间,一部名为《70年,我是主角》...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)