前言
Spring 中使用了三级缓存的设计,来解决单例模式下的属性循环依赖问题。
这句话有两点需要注意
解决问题的方法是「三级缓存的设计」
解决的只是单例模式下的 Bean 属性循环依赖问题,对于多例 Bean 和 Prototype 作用域的 Bean的循环依赖问题,并不能使用三级缓存设计解决。
Bean 的生命周期
Spring Bean 的生命周期可以简单概括为 4 个阶段
实例化(Instantiation)
属性赋值(Populate)
初始化(Initialization)
销毁(Destruction)
什么是循环依赖
public class A {
@Autowired
private B b;
}
public class B {
@Autowired
private A a;
}
如上代码所示,即 A 里面注入 B,B 里面又注入 A。此时,就发生了「循环依赖」。
三级缓存
Spring 中,单例 Bean 在创建后会被放入 IoC 容器的缓存池中,并触发 Spring 对该 Bean 的生命周期管理。
单例模式下,在第一次使用 Bean 时,会创建一个 Bean 对象,并放入 IoC 容器的缓存池中。后续再使用该 Bean 对象时,会直接从缓存池中获取。
保存单例模式 Bean 的缓存池,采用了三级缓存设计,如下代码所示。
/** Cache of singleton objects: bean name --> bean instance */
/** 一级缓存:用于存放完全初始化好的 bean **/
private final Map singletonObjects = new ConcurrentHashMap(256);
/** Cache of early singleton objects: bean name --> bean instance */
/** 二级缓存:存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 */
private final Map earlySingletonObjects = new HashMap(16);
/** Cache of singleton factories: bean name --> ObjectFactory */
/** 三级级缓存:存放 bean 工厂对象,用于解决循环依赖 */
private final Map> singletonFactories = new HashMap>(16);
缓存层级
名称
描述
第一层缓存
singletonObjects
单例对象缓存池,存放的 Bean 已经实例化、属性赋值、完全初始化好(成品)
第二层缓存
earlySingletonObjects
早期单例对象缓存池,存放的 Bean 已经实例化但尚未属性赋值、未执行 init
方法(半成品)
第三层缓存
singletonFactories
单例工厂的缓存
使用三级缓存解决循环依赖
getSingleton方法中三级缓存的使用
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Spring首先从singletonObjects(一级缓存)中尝试获取
Object singletonObject = this.singletonObjects.get(beanName);
// 若是获取不到而且对象在建立中,则尝试从earlySingletonObjects(二级缓存)中获取
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//若是仍是获取不到而且允许从singletonFactories经过getObject获取,则经过singletonFactory.getObject()(三级缓存)获取
singletonObject = singletonFactory.getObject();
//若是获取到了则将singletonObject放入到earlySingletonObjects,也就是将三级缓存提高到二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
getSingleton()
方法中
isSingletonCurrentlyInCreation()
方法用于判断当前单例 Bean 是否正在创建中,即「还没有执行初始化方法」。比如,A 的构造器依赖了 B 对象因此要先去创建 B 对象,或者在 A 的属性装配过程中依赖了 B 对象因此要先创建 B 对象,这时 A 就是处于创建中的状态。
allowEarlyReference
变量表示是否允许从三级缓存 singletonFactories
中经过 singletonFactory
的 getObject()
方法获取 Bean 对象。
分析 getSingleton()
的整个过程,可知三级缓存的使用过程如下
Spring 会先从一级缓存 singletonObjects
中尝试获取 Bean。
若是获取不到,而且对象正在建立中,就会尝试从二级缓存 earlySingletonObjects
中获取 Bean。
若还是获取不到,且允许从三级缓存 singletonFactories
中经过 singletonFactory
的 getObject()
方法获取 Bean 对象,就会尝试从三级缓存 singletonFactories
中获取 Bean。
若是在三级缓存中获取到了 Bean,会将该 Bean 存放到二级缓存中。
第三级缓存为什么可以解决循环依赖
Spring 解决循环依赖的诀窍就在于 singletonFactories
这个三级缓存。 三级缓存中使用到了ObjectFactory
接口,定义如下
public interface ObjectFactory {
T getObject() throws BeansException;
}
在 Bean 建立过程当中,有两处比较重要的匿名内部类实现了该接口。一处是 Spring 利用其建立 Bean 的时候,另外一处就是在 addSingletonFactory
方法中,如下代码所示。
addSingletonFactory(beanName, new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
此处就是解决循环依赖的关键,这段代码发生在 createBeanInstance
以后
此时,单例 Bean 对象已经实例化(可以通过对象引用定位到堆中的对象),但尚未属性赋值和初始化。
Spring 会将该状态下的 Bean 存放到三级缓存中,提早曝光给 IoC 容器(“提早”指的是不必等对象完成属性赋值和初始化后再交给 IoC 容器)。也就是说,可以在三级缓存 singletonFactories
中找到该状态下的 Bean 对象。
解决循环依赖示例分析
public class A {
@Autowired
private B b;
}
public class B {
@Autowired
private A a;
}
在上文章节铺垫的基础上,此处结合一个循环依赖的案例,分析下如何使用三级缓存解决单例 Bean 的循环依赖。
创建对象 A,完成生命周期的第一步,即实例化(Instantiation),在调用 createBeanInstance
方法后,会调用 addSingletonFactory
方法,将已实例化但未属性赋值未初始化的对象 A 放入三级缓存 singletonFactories
中。即将对象 A 提早曝光给 IoC 容器。
继续,执行对象 A 生命周期的第二步,即属性赋值(Populate)。此时,发现对象 A 依赖对象,所以就会尝试去获取对象 B。
继续,发现 B 尚未创建,所以会执行创建对象 B 的过程。
在创建对象 B 的过程中,执行实例化(Instantiation)和属性赋值(Populate)操作。此时发现,对象 B 依赖对象 A。
继续,尝试在缓存中查找对象 A。先查找一级缓存,发现一级缓存中没有对象 A(因为对象 A 还未初始化完成);转而查找二级缓存,二级缓存中也没有对象 A(因为对象 A 还未属性赋值);转而查找三级缓存 singletonFactories
,对象 B 可以通过 ObjectFactory.getObject
拿到对象 A。
继续,对象 B 在获取到对象 A 后,继续执行属性赋值(Populate)和初始化(Initialization)操作。对象 B 完成初始化操作后,会被存放到一级缓存中。
继续,转到「对象 A 执行属性赋值过程并发现依赖了对象 B」的场景。此时,对象 A 可以从一级缓存中获取到对象 B,所以可以顺利执行属性赋值操作。
继续,对象 A 执行初始化(Initialization)操作,完成后,会被存放到一级缓存中。
Spring为何不能解决非单例Bean的循环依赖
Spring 为何不能解决非单例 Bean 的循环依赖?这个问题可以细分为下面几个问题
Spring 为什么不能解决构造器的循环依赖?
Spring 为什么不能解决 prototype
作用域循环依赖?
Spring 为什么不能解决多例的循环依赖?
Spring 为什么不能解决构造器的循环依赖
对象的构造函数是在实例化阶段调用的。
上文中提到,在对象已实例化后,会将对象存入三级缓存中。在调用对象的构造函数时,对象还未完成初始化,所以也就无法将对象存放到三级缓存中。
在构造函数注入中,对象 A 需要在对象 B 的构造函数中完成初始化,对象 B 也需要在对象 A的构造函数中完成初始化。此时两个对象都不在三级缓存中,最终结果就是两个 Bean 都无法完成初始化,无法解决循环依赖问题。
Spring 为什么不能解决prototype作用域循环依赖
Spring IoC 容器只会管理单例 Bean 的生命周期,并将单例 Bean 存放到缓存池中(三级缓存)。Spring 并不会管理 prototype
作用域的 Bean,也不会缓存该作用域的 Bean,而 Spring 中循环依赖的解决正是通过缓存来实现的。
Spring 为什么不能解决多例的循环依赖
多实例 Bean 是每次调用 getBean
都会创建一个新的 Bean 对象,该 Bean 对象并不能缓存。而 Spring 中循环依赖的解决正是通过缓存来实现的。
非单例Bean的循环依赖如何解决
为什么一定要三级缓存
为什么一定要三级缓存,使用两级缓存可以解决循环依赖吗?
带着这个思考,进入下文。
尝试使用两级缓存解决依赖冲突
第三级缓存的目的是为了延迟代理对象的创建,因为如果没有依赖循环的话,那么就不需要为其提前创建代理,可以将它延迟到初始化完成之后再创建。
既然目的只是延迟的话,那么我们是不是可以不延迟创建,而是在实例化完成之后,就为其创建代理对象,这样我们就不需要第三级缓存了。因此,我们可以将 addSingletonFactory()
方法进行改造。
protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 判断一级缓存中不存在此对象
if (!this.singletonObjects.containsKey(beanName)) {
// 直接从工厂中获取 Bean
Object o = singletonFactory.getObject();
// 添加至二级缓存中
this.earlySingletonObjects.put(beanName, o);
this.registeredSingletons.add(beanName);
}
}
}
这样的话,每次实例化完 Bean 之后就直接去创建代理对象,并添加到二级缓存中。
测试结果是完全正常的,Spring 的初始化时间应该也是不会有太大的影响,因为如果 Bean 本身不需要代理的话,是直接返回原始 Bean 的,并不需要走复杂的创建代理 Bean 的流程。
三级缓存的意义
测试证明,二级缓存也是可以解决循环依赖的。为什么 Spring 不选择二级缓存,而要额外多添加一层缓存,使用三级缓存呢?
如果 Spring 选择二级缓存来解决循环依赖的话,那么就意味着所有 Bean 都需要在实例化完成之后就立马为其创建代理,而 Spring 的设计原则是在 Bean 初始化完成之后才为其创建代理。
使用三级缓存而非二级缓存并不是因为只有三级缓存才能解决循环引用问题,其实二级缓存同样也能很好解决循环引用问题。使用三级而非二级缓存并非出于 IOC 的考虑,而是出于 AOP 的考虑,即若使用二级缓存,在 AOP 情形注入到其他 Bean的,不是最终的代理对象,而是原始对象。
你可能感兴趣的:(面试,spring,java,后端,spring面试题,循环依赖)
如何设置HTTP请求中的参数?
数据小爬虫@
http 网络协议 网络
在Java中设置HTTP请求的参数是爬虫开发中的一个常见任务。这可以通过多种方式实现,具体取决于你使用的库。以下将展示如何使用ApacheHttpClient和Java11+的HttpClient设置HTTP请求中的参数。一、使用ApacheHttpClient设置请求参数(一)添加依赖如果你使用的是Maven,可以在pom.xml文件中添加以下依赖:org.apache.httpcomponen
如何使用Java爬虫处理API接口返回的JSON数据?
小爬虫程序猿
API java json 开发语言
处理API接口返回的JSON数据是Java爬虫开发中的一个常见任务。在Java中,有多个库可以帮助我们解析JSON数据,其中最流行的是Jackson和Gson。以下是使用这两个库处理JSON数据的基本步骤和示例代码。使用Jackson处理JSONJackson是一个功能强大的JSON处理库,它不仅可以将JSON字符串解析为Java对象,还可以将Java对象转换为JSON字符串。添加Jackson依
Spring Cache缓存注解深度解析
coder lei
spring 缓存 java
SpringCache缓存注解深度解析一、框架概述SpringCache是Spring框架提供的抽象缓存层,通过注解实现声明式缓存,与具体缓存实现(如Redis、Ehcache)解耦。核心接口CacheManager负责管理不同缓存,@EnableCaching开启注解驱动。二、核心注解详解1.@Cacheable作用:方法结果缓存,首次调用后缓存结果关键参数:@Cacheable(value="
网络原理 初识[Java EE]
猿周LV
Java EE 网络原理 网络 java-ee java
目录网络发展史独立模式网络互联局域网LAN1.基于网络直连2.基于集线器(Hub)组建3.基于交换机(Switch)组建4.基于交换机和路由器(Router)组建广域网WAN网络通信基础IP地址1.概念2.格式端口号1.概念2.格式认识协议1.概念2.作用3.协议分层3.1什么是协议分层3.2分层的作用3.2.1上层不需要了解下层的细节(封装)3.2.2灵活的调整/替换某层的协议4.五元组4.1源
cursor设备ID修改器 支持0.45.11版本最稳定
Ai 编码
Ai编码工具 excel pygame 开发语言
文章精选推荐1JetBrainsAiassistant编程工具让你的工作效率翻倍2ExtraIcons:JetBrainsIDE的图标增强神器3IDEA插件推荐-SequenceDiagram,自动生成时序图4BashSupportPro这个ides插件主要是用来干嘛的?5IDEA必装的插件:SpringBootHelper的使用与功能特点6Aiassistant,又是一个写代码神器 文章正文当你
C++ vector::push_back和Java List.add的区别
da_kao_la
Java Cpp Java Cpp vector List
C++vector::push_back和JavaList.add的区别对象赋值C++和Java在对象赋值方面区别较大,归根到底,还是因为C++和Java中对象存储和引用方式不同。C++中静态建立(即Objobj)的对象的内容(类属性)是存储在栈上的,变量obj直接持有对象本身;Java中建立的对象(Objobj=newObj())的内容(类属性)是存储在堆上的,位于栈上的变量obj只是持有对象的
java学习.五
羽沢31
学习
目录一、本周学习内容:二、学习笔记:(1)Map集合1.Map集合的初步认识:2.Map集合的特点和常用方法3.Map集合的遍历4.Map集合的底层原理(2)Collections工具类1.Collections的常用方法三、编程练习(1)数组练习1.矩阵顺时针打印2.矩阵查找某个值(快捷法)(2)StringJoiner练习1.练习(3)集合统一练习1.扑克牌的洗牌、发牌(无排序)2.统计80个
【用java在控制台实现简单的图书管理系统】
A boy CDEF girl
java 开发语言
用java在控制台实现简单的图书管理系统book包Book类BookList类user包User类AdmiUser类(管理员)NormalUser类(管理员)opertion包IOperation接口FindOpertion(查找图书)AddOpertion(增加图书)DeletOpertion(删除图书)BorrowOpertion(借阅图书)ReturnOpertion(归还图书)ShowOp
JavaEE线程安全的线程池实现
sugar high
Java java-ee java 开发语言
线程虽然比进程更轻量,但是如果创建销毁的频率进一步增加,开销还是很大解决方案:线程池or协程线程池:把线程提前创建好放到池子里,后续用到线程直接从池子里取不必这边申请了。线程用完了也不是还给系统而是放回池子,以备下次再用。为什么线程放在池子里就比从系统申请释放来得更快呢?用户写的代码就是在最上面的应用程序来运行,这里的代码都称为“用户态”运行的代码,有些代码需要调用API进一步的逻辑就会在内核中执
java,深拷贝和浅拷贝
水w
java java 开发语言 拷贝
在Java中,深拷贝(DeepCopy)和浅拷贝(ShallowCopy)是对象拷贝的两种方式,主要区别在于它们如何处理对象的内部引用。目录一、浅拷贝(ShallowCopy)实现方式二、深拷贝(DeepCopy)实现方式1、手动深拷贝2、通过序列化实现深拷贝深拷贝中的注意事项深拷贝的应用场景总结一、浅拷贝(ShallowCopy)浅拷贝是指仅拷贝对象的基本类型字段和引用类型字段的引用,而不是引用
TCP三次握手四次挥手详解与相关面试题
重生之我在成电转码
网络 网络协议 tcp/ip
一、TCP三次握手(Three-WayHandshake)目的:建立可靠的全双工通信通道,确保客户端与服务端都能正常发送和接收数据。1.1三次握手过程第一次握手(SYN):客户端向服务端发送一个SYN(SynchronizeSequenceNumber,同步序列号)报文,请求建立连接。标志位:SYN=1,序列号Seq=x。此时,客户端进入SYN-SENT状态。第二次握手(SYN+ACK):服务端收
深拷贝和浅拷贝
菜鸟蹦迪
java语法 windows
一、定义定义:浅拷贝创建一个新对象,但不复制对象内部的引用指向的对象。复制的是对原始对象内存地址的引用。改变新对象内部的引用所指向的对象会影响原始对象。定义:深拷贝创建一个新对象,并递归地复制原始对象及其引用的所有对象。新对象和原始对象完全独立,修改一个不会影响另一个。二、实例展示importjava.util.ArrayList;importjava.util.List;classShallow
Java【多线程基础4】单例模式中的饿汉模式和懒汉模式
灵魂相契的树
JavaEE初阶 单例模式 java 开发语言 饿汉模式 懒汉模式
文章目录前言一、什么是单例模式二、饿汉模式三、懒汉模式四、多线程环境下的单例模式总结前言各位读者好,我是小陈,这是我的个人主页小陈还在持续努力学习编程,努力通过博客输出所学知识如果本篇对你有帮助,烦请点赞关注支持一波,感激不尽希望我的专栏能够帮助到你:JavaSE基础:基础语法,类和对象,封装继承多态,接口,综合小练习图书管理系统等Java数据结构:顺序表,链表,堆,二叉树,二叉搜索树,哈希表等J
Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结
笑锝没心没肺
JAVA java 开发语言
介绍PermGenspace的全称是PermanentGenerationspace,是指内存的永久保存区域OutOfMemoryError:PermGenspace从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被Load的时候被放入PermGenspace区域,它和和存放Instance的Heap区域不同,GC(G
各类语言的比较
Xia0Mo
java 开发语言
1.设计理念Java:面向对象,强调“一次编写,到处运行”,通过JVM实现跨平台兼容性。Go:简洁高效,注重并发性和编译速度,适合构建高性能分布式系统。C++:面向对象与过程式编程的结合,强调高性能和底层控制,适合系统级编程。Python:强调代码可读性和简洁性,支持多种编程范式(面向对象、函数式、过程式),适合快速开发。2.语法Java:语法严谨,支持类、接口、继承等面向对象特性,代码较为冗长。
Java基础语法练习37(枚举、注解(@Override、@Deprecated和@SuppressWarnings))
橙序研工坊
小白Java的成长 java 开发语言
一、枚举在Java中,枚举(enum)是一种特殊的数据类型,它允许开发者定义一组命名的常量集合先看正常示例,如下代码:publicclassEnum01{publicstaticvoidmain(String[]args){System.out.println(Season.SPRING.getName());}}classSeason{privateStringname;privateStrin
java继承后 赋值返回_Java基础进阶 第三天 单例模式、继承、final
weixin_39757212
java继承后 赋值返回
今日任务1、能够理解单例设计模式2、能够独立使用继承3、能够独立使用final关键字1.代码块1.1.代码块的概念和格式代码块,就是使用大括号括起来的一段代码;书写格式:{代码;}1.2.代码块的分类1.2.1.静态代码块静态代码块,就是使用static修饰的代码块,直接写在类中的代码块;classDemo{static{System.out.pintln("静态代码块")}}2.png静态代码块
mall-swarm微服务商城系统实战:Spring Cloud & Alibaba集成应用
Amarantine Lee
本文还有配套的精品资源,点击获取简介:mall-swarm是一套基于微服务架构的电子商务平台,集成SpringCloud框架和阿里巴巴的Nacos、Sentinel等技术,提供了服务发现、配置管理、流量控制等核心功能。本系统通过使用Eureka或Nacos进行服务注册与发现,Sentinel实现服务保护,以及SpringCloudConfig或Nacos进行动态配置管理,展示了如何构建一个高可用的
Spring Cloud Alibaba入门教程合集-01【微服务和Spring Cloud Alibaba介绍】
图灵学院架构师
Java 前段 spring 微服务 java microservices spring 性能优化
1、微服务介绍1.1系统架构演变随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。从互联网早起到现在,系统架构大体经历了下面几个过程:单体应用架构—>垂直应用架构—>分布式架构—>SOA架构—>微服务架构,当然还有悄然兴起的ServiceMesh(服务网格化)。接下来我们就来了解一下每种系统架构是什么样子的,以及各有什么优缺点。1.1.1单体应用架构互联网早期,一
JavaWeb——HTML
Clrove.11
JavaWeb html 前端
一、什么是HTMLHTML(HyperTextMarkupLanguage):超文本标记语言超文本:超越了文本的限制,比普通文本更强大。除了文字信息还可以定义图片,音频,视频等。标记语言:由标签构成的语言HTML语言都是预定义好的。例如:使用展示超链接,使用展示图片,展示视频。HTML代码直接在浏览器中运行,HTML标签由浏览器解析。二、HTML基础语法HTML基本结构标题填写内容HTML标签不区
java面试题-微服务(一)
qq_51598807
java面试题大全 微服务 云原生
一、相关概念1、什么是集群集群是指将多台服务器集中在一起,每台服务器都实现相同的业务,做相同的事,一起来工作,从而提高工作能力。可以分散服务器压力解决高并发的问题,同时也能预防单节点故障,即一台服务器故障不影响其他服务器正常运行,但没有解决单体应用代码臃肿,业务复杂,维护性差等等问题。2、什么是负载均衡使用了集群后,解决高并发同时有一个新的问题,就是客户端的请求如何分配到多台服务。因此需要通过负载
spring boot 是如何加载配值文件的
花花进修
springboot spring boot
publicSpringApplication(ResourceLoaderresourceLoader,Class...primarySources){this.sources=newLinkedHashSet();this.bannerMode=Mode.CONSOLE;this.logStartupInfo=true;this.addCommandLineProperties=true;th
java面试题-微服务相关组件
Builder 王
java面试题 java 微服务 开发语言
Nacos1.什么是Nacos?Nacos是一个开源项目,由阿里巴巴推出,旨在为构建云原生应用提供动态服务发现、配置管理和服务管理平台。Nacos支持微服务的发现、配置和管理,提供简单易用的特性集,能够快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助用户更敏捷和容易地构建、交付和管理微服务平台,构建以“服务”为中心的现代应用架构,例如微服务范式、云原生范式。此外,Nacos提供
基于javaweb的流浪宠物管理系统的设计与实现
然然学长
java 开发语言 spring boot 毕业设计
运行环境环境说明:开发语言:java框架:springboot,vueJDK版本:JDK1.8数据库:mysql5.7+(推荐5.7,8.0也可以)数据库工具:Navicat11+开发软件:idea/eclipse(推荐idea)Maven包:Maven3.3.9+系统实现5.1个人中心通过设计的个人中心管理功能模块,管理用户可以对相关的个人信息进行管理,比如管理用户可以更新个人账号的密码信息,修
大模型本地部署 Llama 3.1:Ollama、OpenWeb UI 和 Spring AI 的综合指南
m0_74822999
面试 学习路线 阿里巴巴 llama ui spring
本文介绍如何使用Ollama在本地部署Llama3.1:8B模型,并通过OpenWebUI和SpringAI来增强模型交互体验和简化API的调用过程。OllamaOllama是一个开源的服务工具,旨在简化大模型的本地部署和运行过程。用户只需要输入一行命令(如:ollamarunllama3.1),即可在本地硬件环境中部署和使用。Ollama还提供了RESTAPI接口,下文中会介绍如何使用Sprin
Java开发或调用WebService的几种方式
m0_74822999
java 开发语言
Java开发或调用WebService的几种方式文章目录Java开发或调用WebService的几种方式一.JDK自带的JAX-WS方式开发WebService服务1.服务端开发与发布2.客户端开发与测试二.Axis1.4调用.Net返回值为DataSet类型的WebService接口1.相关说明2.Axis1.4客户端WebService服务1.Axis1.4下载2.WebService服务接口
Vue.js表单输入绑定
孤客网络科技工作室
vue.js vue.js 前端 javascript
表单输入绑定在前端处理表单时,我们常常需要将表单输入框的内容同步给JavaScript中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:templatetext=event.target.value">v-model指令帮我们简化了这一步骤:template另外,v-model还可以用于各种不同类型的输入,、元素。它会根据所使用的元素自动使用对应的DOM属性和事件组合:文本类型的和元素会绑
JavaWeb——html表单与CSS
anrui0
JavaWeb入门学习
html表单介绍概念:用于采集用户输入的数据,用于和服务器交互。使用的标签:from。用于定义表单。可以定义一个范围,范围代表采集用户数据的范围。表单属性:1.action:指定提交数据的URL。2.method:指定提交的方式。method分类:一共7种,两种比较常用get:1.请求的参数会在地址栏中显示。2.请求参数的长度是有限制的。3.不太安全post1.请求的参数不会再地址栏中显示。2.请
【完整汇总】近 5 年 JavaScript 新特性完整总览
Hey,我是沉浸式趣谈本文首发于【沉浸式趣谈】,我的个人博客https://yaolifeng.com也同步更新。转载请在文章开头注明出处和版权信息。如果本文对您有所帮助,请点赞、评论、转发,支持一下,谢谢!本文深度解析近5年来JavaScript的所有重要更新,帮助你快速了解JavaScript新特性。ES2024:不断增强的实用性API了解最新的JavaScript特性可以让你的代码更简洁优雅
WebSocket调试神器对决:Apipost VS Apifox
你以为所有API工具都能玩转WebSocket?当你的APP需要实时股票行情推送,当你的游戏要处理千人同屏交互,当你的IM系统必须保障消息零延迟——传统HTTP协议的"一问一答"模式瞬间破功。此刻WebSocket协议才是真正的救世主,这个全双工通信协议能让客户端与服务器建立"永不挂断的热线",但掌握这把利器的开发者们,却常常在调试环节摔得鼻青脸肿:▎传统调试:手写JavaScript+浏览器Co
java线程Thread和Runnable区别和联系
zx_code
java jvm thread 多线程 Runnable
我们都晓得java实现线程2种方式,一个是继承Thread,另一个是实现Runnable。
模拟窗口买票,第一例子继承thread,代码如下
package thread;
public class ThreadTest {
public static void main(String[] args) {
Thread1 t1 = new Thread1(
【转】JSON与XML的区别比较
丁_新
json xml
1.定义介绍
(1).XML定义
扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML使用DTD(document type definition)文档类型定义来组织数据;格式统一,跨平台和语言,早已成为业界公认的标准。
XML是标
c++ 实现五种基础的排序算法
CrazyMizzz
C++ c 算法
#include<iostream>
using namespace std;
//辅助函数,交换两数之值
template<class T>
void mySwap(T &x, T &y){
T temp = x;
x = y;
y = temp;
}
const int size = 10;
//一、用直接插入排
我的软件
麦田的设计者
我的软件 音乐类 娱乐 放松
这是我写的一款app软件,耗时三个月,是一个根据央视节目开门大吉改变的,提供音调,猜歌曲名。1、手机拥有者在android手机市场下载本APP,同意权限,安装到手机上。2、游客初次进入时会有引导页面提醒用户注册。(同时软件自动播放背景音乐)。3、用户登录到主页后,会有五个模块。a、点击不胫而走,用户得到开门大吉首页部分新闻,点击进入有新闻详情。b、
linux awk命令详解
被触发
linux awk
awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
awk处理过程: 依次对每一行进行处理,然后输出
awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
[-F|-f|-v]大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=val
各种语言比较
_wy_
编程语言
Java Ruby PHP 擅长领域
oracle 中数据类型为clob的编辑
知了ing
oracle clob
public void updateKpiStatus(String kpiStatus,String taskId){
Connection dbc=null;
Statement stmt=null;
PreparedStatement ps=null;
try {
dbc = new DBConn().getNewConnection();
//stmt = db
分布式服务框架 Zookeeper -- 管理分布式环境中的数据
矮蛋蛋
zookeeper
原文地址:
http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/
安装和配置详解
本文介绍的 Zookeeper 是以 3.2.2 这个稳定版本为基础,最新的版本可以通过官网 http://hadoop.apache.org/zookeeper/来获取,Zookeeper 的安装非常简单,下面将从单机模式和集群模式两
tomcat数据源
alafqq
tomcat
数据库
JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。
没有使用JNDI时我用要这样连接数据库:
03. Class.forName("com.mysql.jdbc.Driver");
04. conn
遍历的方法
百合不是茶
遍历
遍历
在java的泛
linux查看硬件信息的命令
bijian1013
linux
linux查看硬件信息的命令
一.查看CPU:
cat /proc/cpuinfo
二.查看内存:
free
三.查看硬盘:
df
linux下查看硬件信息
1、lspci 列出所有PCI 设备;
lspci - list all PCI devices:列出机器中的PCI设备(声卡、显卡、Modem、网卡、USB、主板集成设备也能
java常见的ClassNotFoundException
bijian1013
java
1.java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory 添加包common-logging.jar2.java.lang.ClassNotFoundException: javax.transaction.Synchronization
【Gson五】日期对象的序列化和反序列化
bit1129
反序列化
对日期类型的数据进行序列化和反序列化时,需要考虑如下问题:
1. 序列化时,Date对象序列化的字符串日期格式如何
2. 反序列化时,把日期字符串序列化为Date对象,也需要考虑日期格式问题
3. Date A -> str -> Date B,A和B对象是否equals
默认序列化和反序列化
import com
【Spark八十六】Spark Streaming之DStream vs. InputDStream
bit1129
Stream
1. DStream的类说明文档:
/**
* A Discretized Stream (DStream), the basic abstraction in Spark Streaming, is a continuous
* sequence of RDDs (of the same type) representing a continuous st
通过nginx获取header信息
ronin47
nginx header
1. 提取整个的Cookies内容到一个变量,然后可以在需要时引用,比如记录到日志里面,
if ( $http_cookie ~* "(.*)$") {
set $all_cookie $1;
}
变量$all_cookie就获得了cookie的值,可以用于运算了
java-65.输入数字n,按顺序输出从1最大的n位10进制数。比如输入3,则输出1、2、3一直到最大的3位数即999
bylijinnan
java
参考了网上的http://blog.csdn.net/peasking_dd/article/details/6342984
写了个java版的:
public class Print_1_To_NDigit {
/**
* Q65.输入数字n,按顺序输出从1最大的n位10进制数。比如输入3,则输出1、2、3一直到最大的3位数即999
* 1.使用字符串
Netty源码学习-ReplayingDecoder
bylijinnan
java netty
ReplayingDecoder是FrameDecoder的子类,不熟悉FrameDecoder的,可以先看看
http://bylijinnan.iteye.com/blog/1982618
API说,ReplayingDecoder简化了操作,比如:
FrameDecoder在decode时,需要判断数据是否接收完全:
public class IntegerH
js特殊字符过滤
cngolon
js特殊字符 js特殊字符过滤
1.js中用正则表达式 过滤特殊字符, 校验所有输入域是否含有特殊符号function stripscript(s) { var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]"
hibernate使用sql查询
ctrain
Hibernate
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.hibernate.Hibernate;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transa
linux shell脚本中切换用户执行命令方法
daizj
linux shell 命令 切换用户
经常在写shell脚本时,会碰到要以另外一个用户来执行相关命令,其方法简单记下:
1、执行单个命令:su - user -c "command"
如:下面命令是以test用户在/data目录下创建test123目录
[root@slave19 /data]# su - test -c "mkdir /data/test123"
好的代码里只要一个 return 语句
dcj3sjt126com
return
别再这样写了:public boolean foo() { if (true) { return true; } else { return false;
Android动画效果学习
dcj3sjt126com
android
1、透明动画效果
方法一:代码实现
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_main, container, fals
linux复习笔记之bash shell (4)管道命令
eksliang
linux管道命令汇总 linux管道命令 linux常用管道命令
转载请出自出处:
http://eksliang.iteye.com/blog/2105461
bash命令执行的完毕以后,通常这个命令都会有返回结果,怎么对这个返回的结果做一些操作呢?那就得用管道命令‘|’。
上面那段话,简单说了下管道命令的作用,那什么事管道命令呢?
答:非常的经典的一句话,记住了,何为管
Android系统中自定义按键的短按、双击、长按事件
gqdy365
android
在项目中碰到这样的问题:
由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在APP层对按键事件(keyevent)做分解处理,模拟Android系统做法,把keyevent分解成:
1、单击事件:就是普通key的单击;
2、双击事件:500ms内同一按键单击两次;
3、长按事件:同一按键长按超过1000ms(系统中长按事件为500ms);
4、组合按键:两个以上按键同时按住;
asp.net获取站点根目录下子目录的名称
hvt
.net C# asp.net hovertree Web Forms
使用Visual Studio建立一个.aspx文件(Web Forms),例如hovertree.aspx,在页面上加入一个ListBox代码如下:
<asp:ListBox runat="server" ID="lbKeleyiFolder" />
那么在页面上显示根目录子文件夹的代码如下:
string[] m_sub
Eclipse程序员要掌握的常用快捷键
justjavac
java eclipse 快捷键 ide
判断一个人的编程水平,就看他用键盘多,还是鼠标多。用键盘一是为了输入代码(当然了,也包括注释),再有就是熟练使用快捷键。 曾有人在豆瓣评
《卓有成效的程序员》:“人有多大懒,才有多大闲”。之前我整理了一个
程序员图书列表,目的也就是通过读书,让程序员变懒。 写道 程序员作为特殊的群体,有的人可以这么懒,懒到事情都交给机器去做,而有的人又可
c++编程随记
lx.asymmetric
C++ 笔记
为了字体更好看,改变了格式……
&&运算符:
#include<iostream>
using namespace std;
int main(){
int a=-1,b=4,k;
k=(++a<0)&&!(b--
linux标准IO缓冲机制研究
音频数据
linux
一、什么是缓存I/O(Buffered I/O)缓存I/O又被称作标准I/O,大多数文件系统默认I/O操作都是缓存I/O。在Linux的缓存I/O机制中,操作系统会将I/O的数据缓存在文件系统的页缓存(page cache)中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。1.缓存I/O有以下优点:A.缓存I/O使用了操作系统内核缓冲区,
随想 生活
暗黑小菠萝
生活
其实账户之前就申请了,但是决定要自己更新一些东西看也是最近。从毕业到现在已经一年了。没有进步是假的,但是有多大的进步可能只有我自己知道。
毕业的时候班里12个女生,真正最后做到软件开发的只要两个包括我,PS:我不是说测试不好。当时因为考研完全放弃找工作,考研失败,我想这只是我的借口。那个时候才想到为什么大学的时候不能好好的学习技术,增强自己的实战能力,以至于后来找工作比较费劲。我
我认为POJO是一个错误的概念
windshome
java POJO 编程 J2EE 设计
这篇内容其实没有经过太多的深思熟虑,只是个人一时的感觉。从个人风格上来讲,我倾向简单质朴的设计开发理念;从方法论上,我更加倾向自顶向下的设计;从做事情的目标上来看,我追求质量优先,更愿意使用较为保守和稳妥的理念和方法。
&