Spring component-scan实现
componet-scan分为 xml 配置 和 注解配置两种方式,二者入口不同,实现上没太多差别.都是先解析配置,根据配置的 basePackages 用asm扫描.class上是否有@Component注解,若有则生成beanName,注册到容器里即可. context:component-scan/实现配置1<context:component-scan base-package="com.zc"/> 切入点对于自定义标签的解析入口在 DefaultBeanDefinitionDocumentReader.parseCustomElement(ele); 里.1.先根据标签获取parser,这里是 ComponentScanBeanDefinitionParser 调用12345678910111213141516171819202122- NamespaceHandlerSupport.parse(): 根据元素获取parser进行处理,这里使用的是ComponentScanBeanDefinitionParser -...
spring-boot启动流程
spring-boot 启动 spingboot-start SpringApplication构造方法 使用 SpringFactoriesLoader 在 classpath 中查找并加载所有可用的 ApplicationContextInitializer 使用 SpringFactoriesLoader 在 classpath 中查找并加载所有可用的 ApplicationListener 通过stackTrace里的main方法查找启动类 SpringApplication.run() 创建StopWatch计时器 通过 SpringFactoriesLoader 查找并加载 SpringApplicationRunListener 列表,调用 SpringApplicationRunListener.started() 方法 创建Environment configureEnvironment() listeners.environmentPrepared(): 广播 ApplicationEnvironmentPreparedEvent...
idea搭建spring-boot环境
idea搭建spring-boot环境显示taggit tag 选择 v2.1.5.RELEASE 版本,这是我们项目里现在在用的版本,还比较新,最新的目前是 2.3.0. 拉自己的分支 建立我自己的分支,以后代码注释都写在这个分支上.v2.1.5.RELEASE-zc git checkout -b v2.1.5.RELEASE-zc v2.1.5.RELEASE v2.1.5.RELEASE 这个版本是可以选择 maven 或 gradle 构建的,我这里选的maven. 工程依赖的jar包很多,大概要下个半小时多. 将本地分支推到远程git push origin v2.1.5.RELEASE-zc 建立关联git push –set-upstream origin v2.1.5.RELEASE-zc 看看代码量spring-boot 总共代码45w行,纯代码 27w 行. idea attach sourceidea 的配置最终都落到 .idea 下的 xml 里,搜索 springboot 的 maven 配置文件,修改里面的...
Tomcat处理请求流程
tomcat处理请求组件Server123456789101112131415Server|-- Service|--|-- Connector|--|--|-- Prototal|--|--|--|-- Endpoint|--|--|--|--|-- Acceptor|--|--|--|--|-- Executor|--|--|--|-- Processor|--|--|-- Mapper|--|--|-- CoyteAdapter|--|-- Container|--|--|--|-- Host|--|--|--|-- Context|--|--|--|-- Wrapper|--|-- Executor Http11NioProtocol12345678910111213Http11NioProtocol|-- NioEndpoint|--|-- LimitLatch|--|-- Acceptor|--|-- Poller|--|-- Poller池|--|-- SocketProcessor|--|-- Executor|--|-- PollerEvent|--|--...
Tomcat Session机制
tomcat session相关类12345org.apache.catalina.ManagerStandardManagerSessionIdGenerator Manager实现类Manager 用于管理 session.默认实现是 StandardManager,基类 ManagerBase. 123456789101112Manager ClusterManager (org.apache.catalina.ha) ClusterManagerBase (org.apache.catalina.ha.session) BackupManager (org.apache.catalina.ha.session) DeltaManager (org.apache.catalina.ha.session) ManagerBase (org.apache.catalina.session) PersistentManagerBase (org.apache.catalina.session)...
Tomcat实现分布式session
tomcat实现分布式sessiontomcat-redis-session-manager 使用Copy the following files into the TOMCAT_BASE/lib directory: 123tomcat-redis-session-manager-VERSION.jarjedis-2.5.2.jarcommons-pool2-2.2.jar 配置 TOMCAT_HOME/conf/context.xml 12345<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" /><Manager className="com.radiadesign.catalina.session.RedisSessionManager" host="localhost" port="6379"...
Tomcat Lifecycle
LifeCycleLifeCycle 相关类LifeCycle 接口中的状态扭转注释,如下: 12345678910111213141516171819202122232425262728* start()* -----------------------------* | |* | init() |* NEW -»-- INITIALIZING |* | | | | ------------------«-----------------------* | | |auto | | |* | | \|/ start() \|/ \|/ auto auto stop() |* | | ...
Tomcat启动流程
tomcat...
布隆过滤器
布隆过滤器what布隆过滤器(Bloom Filter).是一个很长的 二进制向量 和 一系列随机映射 函数. 之所以叫 filter,是在缓存之前,把不存在的 key 给拦截掉. 本质是 一个位数组: 位数组 就是 数组 的 每个元素 都只占用 1 bit,并且每个元素只能是 0 或 1. 用于判断: 某个元素 一定不存在 或者 可能存在 于 一个集合中. 布隆过滤器除了一个位数组,还有 K 个哈希函数. 插入一个元素加入布隆过滤器:使用 K 个 哈希函数 对元素值 进行 K 次计算,得到 K 个哈希值.根据得到的哈希值,在 位数组中 把对应下标的值置为 1. 查询当查询 w 是否存在时,可以再通过这 k 个 哈希函数,如果算出来所在的位置均为1,则表示 w 可能存在(注意是可能存在),否则一定不存在. 优缺点1.优点空间效率 和 查询时间 都远远超过一般的算法. 2.缺点有一定的 误识别率 和 删除困难 数组的容量即使再大,也是有限的. 随着元素的增加,插入的元素就会越多,位数组中被置为 1...
Redis实现分布式锁
Redis实现分布式锁要考虑的点 互斥(独占,只能有一个客户端获取锁) 不能死锁 容错(只要大部分 redis 节点创建了这把锁就认为成功获取到锁) 支持重入,超时获取锁等特性 redis实现分布式锁1.使用set1.1.加锁1SET key randomValue NX PX 30000 NX: (not exists)表示只有 key 不存在的时候才会设置成功.(如果此时 redis 中存在这个 key,那么设置失败,返回 nil)PX 30000: 30s 后 key 失效,意味着 30s 后锁自动释放. 随机数 randomValue 可以使用 时间戳 + 客户端编号 的方式 生成随机数. 1.2.释放锁123456-- 删除锁的时候,找到 key 对应的 value,跟自己传过去的 value 做比较,如果是一样的才删除.保证解的是自己加的锁if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1])else ...