Spring容器功能扩展的方法
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,本篇内容介绍了"Spring容器功能扩展的方法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、Ap
千家信息网最后更新 2025年02月02日Spring容器功能扩展的方法
本篇内容介绍了"Spring容器功能扩展的方法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
1、ApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("beanFactory.xml");public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null);}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); }}
public void setConfigLocations(String[] locations) { if (locations != null) { this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { //解析配置文件地址并记录 this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; }}
2、扩展功能
if (refresh) { refresh();}//ApplicationContext的核心功能几乎都在此方法中实现了,逻辑清晰明了public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //1.准备刷新上下文环境,做准备工作,例如对系统属性及环境变量初始化及验证 prepareRefresh(); //2.初始化BeanFactory,并对XML文件进行读取 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //3.对BeanFactory进行各种功能填充 prepareBeanFactory(beanFactory); try { //空实现,留给子类扩展 postProcessBeanFactory(beanFactory); //4.激活各种BeanFactory处理器 invokeBeanFactoryPostProcessors(beanFactory); //5.注册BeanPostProcessor,这里只是注册,真正调用是在getBean的时候 registerBeanPostProcessors(beanFactory); //6.为上下文初始化Message源,国际化处理 initMessageSource(); //7.初始化应用消息广播,并放入applicationEventMulticaster中 initApplicationEventMulticaster(); //空实现,留给子类实现来初始化其它的bean onRefresh(); //8.在所有注册的bean中查找Listener bean,并注册到广播中 registerListeners(); //9.初始化非延迟加载单例 finishBeanFactoryInitialization(beanFactory); //10.完成刷新过程,通知生命处理器刷新过程,同时发出ContextRefreshEvent通知别人 finishRefresh(); } }}
3、步骤1:准备刷新上下文环境
//做准备工作,例如对系统属性及环境变量初始化及验证protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); synchronized (this.activeMonitor) { this.active = true; } //空实现,留给子类覆盖 initPropertySources(); //验证需要的属性文件是否都已经放入环境中 getEnvironment().validateRequiredProperties();}
4、步骤2:加载BeanFactory
//经过该函数之后ApplicationContext就有了BeanFactory的全部功能ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //初始化BeanFactory,并进行XML文件读取,并将得到的beanFactory记录,方便以后获取 refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); return beanFactory;}
@Overrideprotected final void refreshBeanFactory() throws BeansException { try { //直接new DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //定制BeanFactory,这里已经开始了对BeanFactory的扩展 customizeBeanFactory(beanFactory); //加载BeanDefinition loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { //记录beanFactory this.beanFactory = beanFactory; } }}
//定制BeanFactory,这里已经开始了对BeanFactory的扩展protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //设置是否允许覆盖同名称的不同定义的对象 if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //设置是否允许bean之间存在循环依赖 if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } //提供了@Qualifier和@Autowired注解的支持 beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());}
//加载BeanDefinitionprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory){ //创建XmlBeanDefinitionReader来读取XML配置文件 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //对XmlBeanDefinitionReader进行环境变量的设置 beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); //走到这步之后,后面逻辑和BeanFactory中讲的读取配置文件一样的 loadBeanDefinitions(beanDefinitionReader);}
5、步骤3:对BeanFactory进行各种功能填充
prepareBeanFactory(beanFactory);//进入函数prepareBeanFactory之前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也在此展开protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); //设置beanFactory的表达式语言SpEL处理器,Spring3增加了表达式语言的支持 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); //为beanFactory增加一个默认的属性编辑器propertyEditor,在配置文件中可以解析Date(2018-07-27类型) beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //5.1添加ApplicationContextAwareProcessor处理器,见下面分析 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //5.1时已经分析了,这里设置忽略依赖 beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); //后面删去了部分代码}
5.1、添加ApplicationContextAwareProcessor处理器
//ApplicationContextAwareProcessor实现了BeanPostProcessor,在Spring源码分析4之初始化Bean中我们分析过,Spring激活init-method//前后,会调用BeanPostProcessor的before和after方法,我们看一下ApplicationContextAwareProcessor的这两个方法直接返回,不做处理public Object postProcessAfterInitialization(Object bean, String beanName) { return bean;}
public Object postProcessBeforeInitialization(final Object bean, String beanName){ //删去部分代码,留下核心代码 invokeAwareInterfaces(bean); return bean;}
//实现这些接口的bean在被初始化之后,可以取得对应的资源,相应的这边已经设置了相关属性,因此需要在Spring做依赖注//入的时候忽略掉它们,见下面代码private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver( new EmbeddedValueResolver(this.applicationContext.getBeanFactory())); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } }}
6、步骤4:激活各种BeanFactory处理器
注意是BeanFactoryPostProcessor,不是BeanPostProcessor. BeanFactoryPostProcessor接口和BeanPostProcessor类似,可以对bean的定义进行处理,Spring IOC容器允许BeanFactoryPostProcessor在容器实例化任何其他的bean之前读取配置元数据,并修改它. 可以实现Ordered接口来设置BeanFactoryPostProcessor的执行顺序. BeanFactoryPostProcessor的典型应用:PropertyPlaceholderConfigurer. PropertyPlaceholderConfigurer间接继承了BeanFactoryPostProcessor接口,当Spring加载任何实现了这个接口的bean的配置时,都会在bean工厂载入所有bean配置之后执行postProcessBeanFactory方法. 在PropertyResourceConfigurer中实现了postProcessBeanFactory方法,在方法中分别得到配置,将得到的配置转换为合适的类型,最后将配置内容告诉BeanFactory. 正是通过实现BeanFactoryPostProcessor接口,BeanFactory会在实例化任何bean之前获取配置信息,从而能够正确解析bean描述文件中的变量引用.
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //待补充}
7、步骤5:注册BeanPostProcessor
//这里只是注册,而不是调用,真正调用是在bean实例化阶段进行的.BeanFactory中并没有实现后处理器的自动注册,需要手动注册,而在//ApplicationContext中实现了自动注册功能
registerBeanPostProcessors(beanFactory);
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { //获取所有实现了BeanPostProcessor接口的配置文件中配置的bean的id名 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); //优先级高的 ListpriorityOrderedPostProcessors = new ArrayList (); List internalPostProcessors = new ArrayList (); //排序的 List orderedPostProcessorNames = new ArrayList (); //无序的 List nonOrderedPostProcessorNames = new ArrayList (); for (String ppName : postProcessorNames) { if (isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } //对优先级的进行排序并注册 OrderComparator.sort(priorityOrderedPostProcessors); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); List orderedPostProcessors = new ArrayList (); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } //对排序的进行排序并注册 OrderComparator.sort(orderedPostProcessors); registerBeanPostProcessors(beanFactory, orderedPostProcessors); List nonOrderedPostProcessors = new ArrayList (); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } //对无序的进行注册 registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); OrderComparator.sort(internalPostProcessors); registerBeanPostProcessors(beanFactory, internalPostProcessors); beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());}
private void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, ListpostProcessors) { for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); }}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { //先删再加保证了beanPostProcessor的唯一性,其实就是用beanPostProcessors属性记录BeanPostProcessor this.beanPostProcessors.remove(beanPostProcessor); this.beanPostProcessors.add(beanPostProcessor); if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; }}ListbeanPostProcessors = new ArrayList ();
8、步骤6:为上下文初始化Message源,国际化处理
initMessageSource();protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //如果容器中配置了messageSource,该属性是硬编码配置的 if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); } else { //如果没有配置,则new一个临时的MessageSource DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; //注册到容器中 beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); }}
9、步骤7:初始化应用消息广播,并放入applicationEventMulticaster中
initApplicationEventMulticaster();
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); } else { //否则使用默认的ApplicationEventMulticaster this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); }}
10、步骤8:在所有注册的bean中查找Listener bean,并注册到广播中
registerListeners();protected void registerListeners() { for (ApplicationListener> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } //配置文件注册的监听处理器 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String lisName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(lisName); }}
11、步骤9:初始化非延迟加载单例
finishBeanFactoryInitialization(beanFactory);protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //配置ConversionService,也是类型转换器 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)); } //冻结配置,冻结所有的bean定义,说明注册的bean定义将不会被修改或做任何进一步的处理 beanFactory.freezeConfiguration(); //初始化非延迟加载,ApplicationContext的默认行为就是在启动时将所有的非延迟加载的单例提前进行实例化 beanFactory.preInstantiateSingletons();}
public void preInstantiateSingletons() throws BeansException { ListbeanNames; synchronized (this.beanDefinitionMap) { beanNames = new ArrayList (this.beanDefinitionNames); } 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 = (factory instanceof SmartFactoryBean && ((SmartFactoryBean>) factory).isEagerInit()); if (isEagerInit) { getBean(beanName); } } else { //初始化bean getBean(beanName); } } }}
12、 步骤10:完成刷新过程
//通知生命处理器刷新过程,同时发出ContextRefreshEvent通知别人finishRefresh();protected void finishRefresh() { //初始化LifecycleProcessor initLifecycleProcessor(); //启动所有实现了Lifecycle接口的bean getLifecycleProcessor().onRefresh(); //发出ContextRefreshedEvent事件,以保证对应的监听器可以做进一步的处理 publishEvent(new ContextRefreshedEvent(this));}
"Spring容器功能扩展的方法"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
配置
处理
文件
步骤
功能
处理器
接口
方法
属性
容器
环境
过程
延迟
上下
上下文
代码
变量
实例
准备
分析
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
四川联商宝网络技术有限公司
服务器日志事件id37
微生物资源数据库平台
数据库中的知识点
南京1u服务器订购
读软件开发学校
嘻哈网络技术
数据库用户跟密码
网络安全朋友圈内容
山东网络安全测试
smtp服务器是用来
厦门盖亚网络技术
日常生活网络安全问题
网络安全工程师自学网站
苹果服务器维护
mc服务器末地
安徽品效网络技术有限公司
辽宁省科技互联网部主任
深美互联网络科技
太原网络安全学习容易且快速
宽带网络技术考试试题
改数据库字符编码
珠海电商软件开发常见问题
qq的域名邮箱服务器
岳阳软件开发系列
怎样用本地服务器挖矿
三缺一网络技术有限公司怎么样
数据库企业版软件
华为无线网络技术支持
安徽品效网络技术有限公司