refresh() -> invokeBeanFactoryPostProcessors()

调用各种BeanFactory处理器,如:

解析占位符${}中对应属性值的替换工作

扩充

通常如果想对BeanFactory中的数据进行修改时可以通过实现BeanFactoryPostProcessor来进行实现

@FunctionalInterface
public interface BeanFactoryPostProcessor {void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

针对BeanFactory

同理,如果想要修改BeanDefinition中的信息时可以实现BeanDefinitionRegistryPostProcessor进行操作

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

针对BeanDefinition,而BeanFactory已包含;BeanDefinitionRegistry的作用为对BeanDefinition的增删改查操作

如果一个类实现了BeanDefinitionRegistryPostProcessor,那么他的postProcessBeanFactory()方法可以跟其他的BeanFactoryPostProcessor一起执行

所有后置Registry的对象都是对前面名称对象的增删改查的操作

有关IOC中对象执行顺序的说明

PriorityOrdered > Ordered > 没有实现任何排序接口的对象

public interface PriorityOrdered extends Ordered {}public interface Ordered {int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;int LOWEST_PRECEDENCE = Integer.MAX_VALUE;int getOrder();
}

invokeBeanFactoryPostProcessors()

实例化并且调用所有已经注册了的BeanFactoryPostProcessor,遵循指明的顺序

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值,并且实例化调用执行所有已经注册的beanFactoryPostProcessorPostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}

getBeanFactoryPostProcessors()

默认情况下,通过此来获取已经注册的BFPP(BeanFactoryPostProcessor),但是默认是空的,此处也可以将自定义的BFPP获取到

自定义BFPP

  1. 实现BFPP接口

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("自定义BeanFactoryPostProcessor");}
    }
    
  2. 将自定义BFPP注入到IOC容器或者自定义ClassPathXmlApplicationContext重写在getBeanFactoryPostProcessors()调用之前的任意方法调用父类的addBeanFactoryPostProcessor()进行BFPP的注入,如:customizeBeanFactory()

    import com.armin.self_bfpp.MyBeanFactoryPostProcessor;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyClassPathApplicationContext extends ClassPathXmlApplicationContext {public MyClassPathApplicationContext(String... configLocations) throws BeansException {super(configLocations);}@Overrideprotected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());super.customizeBeanFactory(beanFactory);}
    }
    

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

实例化调用执行所有已经注册的beanFactoryPostProcessor

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.// 无论是什么情况,优先执行BeanDefinitionRegistryPostProcessors// 将已经执行过的BFPP存储在processedBeans中,防止重复执行Set<String> processedBeans = new HashSet<>();// 判断beanfactory是否是BeanDefinitionRegistry类型,此处是DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,所以为trueif (beanFactory instanceof BeanDefinitionRegistry) {// 类型转换BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;// 此处希望大家做一个区分,两个接口是不同的,BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子集// BeanFactoryPostProcessor主要针对的操作对象是BeanFactory,而BeanDefinitionRegistryPostProcessor主要针对的操作对象是BeanDefinition// 存放BeanFactoryPostProcessor的集合List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();// 存放BeanDefinitionRegistryPostProcessor的集合List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();// 首先处理入参中的beanFactoryPostProcessors,遍历所有的beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor// 和BeanFactoryPostProcessor区分开for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {// 如果是BeanDefinitionRegistryPostProcessorif (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;// 直接执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法registryProcessor.postProcessBeanDefinitionRegistry(registry);// 添加到registryProcessors,用于后续执行postProcessBeanFactory方法registryProcessors.add(registryProcessor);} else {// 否则,只是普通的BeanFactoryPostProcessor,添加到regularPostProcessors,用于后续执行postProcessBeanFactory方法regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.// 用于保存本次要执行的BeanDefinitionRegistryPostProcessorList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.// 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类// 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanNameString[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// 遍历处理所有符合规则的postProcessorNamesfor (String ppName : postProcessorNames) {// 检测是否实现了PriorityOrdered接口if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 获取名字对应的bean实例,添加到currentRegistryProcessors中currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));// 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行processedBeans.add(ppName);}}// 按照优先级进行排序操作sortPostProcessors(currentRegistryProcessors, beanFactory);// 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法registryProcessors.addAll(currentRegistryProcessors);// 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);// 执行完毕之后,清空currentRegistryProcessorscurrentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.// 调用所有实现Ordered接口的BeanDefinitionRegistryPostProcessor实现类// 找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName,// 此处需要重复查找的原因在于上面的执行过程中可能会新增其他的BeanDefinitionRegistryPostProcessorpostProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {// 检测是否实现了Ordered接口,并且还未执行过if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {// 获取名字对应的bean实例,添加到currentRegistryProcessors中currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));// 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行processedBeans.add(ppName);}}// 按照优先级进行排序操作sortPostProcessors(currentRegistryProcessors, beanFactory);// 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法registryProcessors.addAll(currentRegistryProcessors);// 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);// 执行完毕之后,清空currentRegistryProcessorscurrentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.// 最后,调用所有剩下的BeanDefinitionRegistryPostProcessorsboolean reiterate = true;while (reiterate) {reiterate = false;// 找出所有实现BeanDefinitionRegistryPostProcessor接口的类postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// 遍历执行for (String ppName : postProcessorNames) {// 跳过已经执行过的BeanDefinitionRegistryPostProcessorif (!processedBeans.contains(ppName)) {// 获取名字对应的bean实例,添加到currentRegistryProcessors中currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));// 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行processedBeans.add(ppName);reiterate = true;}}// 按照优先级进行排序操作sortPostProcessors(currentRegistryProcessors, beanFactory);// 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法registryProcessors.addAll(currentRegistryProcessors);// 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);// 执行完毕之后,清空currentRegistryProcessorscurrentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.// 调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);// 最后,调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);} else {// Invoke factory processors registered with the context instance.// 如果beanFactory不归属于BeanDefinitionRegistry类型,那么直接执行postProcessBeanFactory方法invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 到这里为止,入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,下面开始处理容器中// 所有的BeanFactoryPostProcessor// 可能会包含一些实现类,只实现了BeanFactoryPostProcessor,并没有实现BeanDefinitionRegistryPostProcessor接口// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// 找到所有实现BeanFactoryPostProcessor接口的类String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessorList<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName//        List<String> orderedPostProcessorNames = new ArrayList<>();List<BeanFactoryPostProcessor> orderedPostProcessor = new ArrayList<>();// 用于存放普通BeanFactoryPostProcessor的beanName//       List<String> nonOrderedPostProcessorNames = new ArrayList<>();List<BeanFactoryPostProcessor> nonOrderedPostProcessorNames = new ArrayList<>();// 遍历postProcessorNames,将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开for (String ppName : postProcessorNames) {// 跳过已经执行过的BeanFactoryPostProcessorif (processedBeans.contains(ppName)) {// skip - already processed in first phase above}// 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessorselse if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}// 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName到orderedPostProcessorNameselse if (beanFactory.isTypeMatch(ppName, Ordered.class)) {//              orderedPostProcessorNames.add(ppName);orderedPostProcessor.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));} else {// 添加剩下的普通BeanFactoryPostProcessor的beanName到nonOrderedPostProcessorNames//              nonOrderedPostProcessorNames.add(ppName);nonOrderedPostProcessorNames.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.// 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序sortPostProcessors(priorityOrderedPostProcessors, beanFactory);// 遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.// 创建存放实现了Ordered接口的BeanFactoryPostProcessor集合//        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());// 遍历存放实现了Ordered接口的BeanFactoryPostProcessor名字的集合//       for (String postProcessorName : orderedPostProcessorNames) {// 将实现了Ordered接口的BeanFactoryPostProcessor添加到集合中//           orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));//        }// 对实现了Ordered接口的BeanFactoryPostProcessor进行排序操作//      sortPostProcessors(orderedPostProcessors, beanFactory);sortPostProcessors(orderedPostProcessor, beanFactory);// 遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法//     invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessor, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.// 最后,创建存放普通的BeanFactoryPostProcessor的集合//     List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());// 遍历存放实现了普通BeanFactoryPostProcessor名字的集合//     for (String postProcessorName : nonOrderedPostProcessorNames) {// 将普通的BeanFactoryPostProcessor添加到集合中//          nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));//     }// 遍历普通的BeanFactoryPostProcessor,执行postProcessBeanFactory方法//       invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(nonOrderedPostProcessorNames, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...// 清除元数据缓存(mergeBeanDefinitions、allBeanNamesByType、singletonBeanNameByType)// 因为后置处理器可能已经修改了原始元数据,例如,替换值中的占位符beanFactory.clearMetadataCache();
}

整个方法的大致执行流程

  1. 首先执行beanFactory调用addBeanFactoryPostProcessor添加的BeanFactoryPostProcessor

    如果该类为BeanDefinitionRegistryPostProcessor的实现先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法再将该实例放入集合中后续统一执行父接(BeanFactoryPostProcessor)口中的postProcessBeanFactory方法

  2. BeanFactory中获取BeanDefinitionRegistryPostProcessor并且实现PriorityOrdered接口的BeanName,然后通过BeanFactory<T> T getBean(String name, Class<T> requiredType)方法获取实例(该方法会调用实例化Bean中的creatBean方法),放入集合先统一执行postProcessBeanDefinitionRegistry再将该对象放入另一个集合后续统一执行postProcessBeanFactory方法

  3. 再次重复第2点(不一样的地方:PriorityOrdered改为Ordered

  4. 执行剩下的BeanDefinitionRegistryPostProcessor考虑可能存在执行上一步的时候在BeanDefinitionRegistryPostProcessor 对象中调用postProcessBeanDefinitionRegistry会添加新的BeanDefinitionRegistryPostProcessor 对象此处会循环将所有的BeanDefinitionRegistryPostProcessor 执行完

  5. 获取BeanFactoryPostProcessor类型的所有BeanName根据是否实现PriorityOrdered,Ordered和没有实现任何排序接口的依次从前往后执行postProcessBeanFactory方法

invokeBeanDefinitionRegistryPostProcessors()

调用给定BeanDefinitionRegistryPostProcessor Bean对象

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {//遍历 postProcessorsfor (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {//调用 postProcessor 的 postProcessBeanDefinitionRegistry以使得postProcess往registry注册BeanDefinition对象postProcessor.postProcessBeanDefinitionRegistry(registry);}
}

invokeBeanFactoryPostProcessors()

调用给定的BeanFactoryPostProcessor类型Bean对象

private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {//遍历postProcessorsfor (BeanFactoryPostProcessor postProcessor : postProcessors) {//回调 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法,使得每个postProcessor对象都可以对// beanFactory进行调整postProcessor.postProcessBeanFactory(beanFactory);}
}

测试从BeanFactory中根据类型获取到的BeanDefinitionRegisterPostProcessor在其中又添加新的BeanDefinitionRegisterPostProcessor执行结果

MyBeanDefinitionRegisterPostProcessor

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;public class MyBeanDefinitionRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {System.out.println("执行postProcessBeanDefinitionRegistry()--" + getClass().getName());BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MySelfBeanDefinitionRegisterPostProcessor.class);builder.addPropertyValue("name", "armin");registry.registerBeanDefinition("mySelfBdrpp",builder.getBeanDefinition());}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("执行postProcessBeanFactory()--" + getClass().getName());}
}

MySelfBeanDefinitionRegisterPostProcessor

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;public class MySelfBeanDefinitionRegisterPostProcessor implements BeanDefinitionRegistryPostProcessor {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {System.out.println("执行postProcessBeanDefinitionRegistry()--" + getClass().getName());}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("执行postProcessBeanFactory()--" + getClass().getName());}
}

Test

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("armin-self-bdrpp.xml");}}

armin-self-bdrpp.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.armin.self_bdrpp.MyBeanDefinitionRegisterPostProcessor"></bean></beans>

执行结果

> Task :spring-debug:Test.main()
执行postProcessBeanDefinitionRegistry()--com.armin.self_bdrpp.MyBeanDefinitionRegisterPostProcessor
执行postProcessBeanDefinitionRegistry()--com.armin.self_bdrpp.MySelfBeanDefinitionRegisterPostProcessor
执行postProcessBeanFactory()--com.armin.self_bdrpp.MyBeanDefinitionRegisterPostProcessor
执行postProcessBeanFactory()--com.armin.self_bdrpp.MySelfBeanDefinitionRegisterPostProcessorBUILD SUCCESSFUL in 2m 1s

refresh() -> invokeBeanFactoryPostProcessors()相关推荐

  1. http头部信息解析

    HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详 细内容请参考RFC2616.HTTP协议采用了请求/响应模型.客 ...

  2. http协议头信息详解

    注:此文复制而来,只为便于学习! 通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可 选的消息体组成.H ...

  3. HTTP协议(HyperText Transfer Protocol,超文本传输协议)

    HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准. HTTP是一个基于TCP/IP通信 ...

  4. SpringBoot(1.5.6.RELEASE)源码解析(一)

    启动SpringBoot,需要在入口函数所在的类上添加@SpringBootApplication注解 1 @SpringBootApplication 2 public class Applicat ...

  5. HTTP协议SSL协议HTTPS协议

    文章目录 1.HTTP协议 1.1.HTTP 简介 1.2.HTTP 消息结构 1.3.HTTP 请求方法 1.4.HTTP 响应头信息 1.5.HTTP 状态码 1.6.HTTP协议的优点与缺点 2 ...

  6. HTTP协议的头信息详解

    HTTP协议的头信息详解 http://blog.csdn.net/guoguo1980/archive/2008/07/14/2649658.aspx HTTP协议的头信息详解 HTTP(Hyper ...

  7. ImportBeanDefinitionRegistrar向容器中注册bean

    一.ImportBeanDefinitionRegistrar 我们先来看看ImportBeanDefinitionRegistrar是个什么鬼,点击进入ImportBeanDefinitionReg ...

  8. Java Servlet和JSP教程

    http://www.bccn.net/article/web/jsp/jc/200409/72.html 简介 这是一个比较完整的Servlet.JSP教程,包含大量的实用资料和示例,仙人掌工作室倾 ...

  9. 最全的http头部信息分析(转载)

    1.http 头信息详解 HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616.HTTP协议 ...

最新文章

  1. oracle 连接池sql跟踪,实现SQLServer、MySQL和oracle数据库连接池
  2. HTML-语义类标签
  3. 搜狗浏览器也可以直接安装Chrome插件,太棒了
  4. C++笔记-shared_ptr与weak_ptr需要注意的地方
  5. 《数据库设计入门经典》读书笔记——第二章:工作场所中的数据库建模
  6. 最大化最小值 | | 最小化最大值
  7. Linux详解系列2- 这100条常见命令你都用过哪些?
  8. C# 在 webBrowser 光标处插入 html代码 .
  9. [鸟哥linux视频教程整理]03_03_bash特性详解续
  10. atitit 编程语言概念与原理
  11. atitit.重装系统需要备份的资料总结 o84..
  12. FontLab VI(字体制作软件)v6.1.4.7043中文版
  13. Google微软IBM能打败亚马逊AWS的理由很丰满,进展却骨感
  14. 个人业务存在的开票和个税问题,自然人代开核定征收解决
  15. 经典排序算法之--冒泡排序
  16. 如何实现Linux下的U盘(USB Mass Storage)驱动
  17. 电视K歌软件哪个好?这10款最火,最好用的电视K歌软件,赶紧收藏
  18. Linux: systemd 启动代码分析
  19. InnoDB——架构、日志、表和索引
  20. project 2016 显示、取消任务序号

热门文章

  1. 幅频响应 matlab画法,matlab绘制数字滤波器的幅频响应曲线
  2. 图解Bellman Ford算法
  3. 外部数据库数据引入出现错误的小小解决方法
  4. 【计算机毕业设计】网上生鲜销售系统
  5. 大数据:Kettle导入数据到HDFS
  6. DSP程序优化导致结果出错
  7. dsp28335下载程序到flash出现的问题
  8. STM32实现PWM移相任意角度
  9. matlab中rastrigin图形绘制,matlab函数function
  10. 如何将文件自动备份到电脑其他硬盘或者百度网盘?