我们知道BeanDefintion定义了Bean在IoC容器内的基本数据结构。在学习IoC之前先了解BeanDefition对我们理解IoC容器是有帮助的。

首先BeanDefinition是一个接口,继承了AttributeAccessor和BeanMetadataElement。

我们主要来学习下他的一个实现类,AbstractBeanDefinition。

这虽然是一个抽象类,但是提供了BeanDefinition接口的全部实现。是一个基本的框架。其子类有RootBeanDefinition(表示父级),ChildBeanDefinition(表示子级)和GenericBeanDefinition(一般的BeanDefinition实现)。

来看代码:

 /*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.beans.factory.support; import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set; import org.springframework.beans.BeanMetadataAttributeAccessor;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.core.io.DescriptiveResource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; /**
* Base class for concrete, full-fledged {@link BeanDefinition} classes,
* factoring out common properties of {@link GenericBeanDefinition},
* {@link RootBeanDefinition}, and {@link ChildBeanDefinition}.
*
* <p>The autowire constants match the ones defined in the
* {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
* interface.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Rob Harrop
* @author Mark Fisher
* @see GenericBeanDefinition
* @see RootBeanDefinition
* @see ChildBeanDefinition
*/
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable { public static final String SCOPE_DEFAULT = ""; /***************************自动注入时的策略***************************/ public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; @Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; /***************************依赖检查的策略***************************/
//不做检查
public static final int DEPENDENCY_CHECK_NONE = 0; //检查除简单类型属性以及集合类型属性外的引用类型属性
public static final int DEPENDENCY_CHECK_OBJECTS = 1; //检查简单类型属性以及集合类型属性
public static final int DEPENDENCY_CHECK_SIMPLE = 2; //全部检查
public static final int DEPENDENCY_CHECK_ALL = 3; public static final String INFER_METHOD = "(inferred)"; //表示这个Bean的类,可能是字符串,比如"com.insaneXs.TestA",也可能是class对象
private volatile Object beanClass; //表示这个bean的范围
private String scope = SCOPE_DEFAULT; //是否是抽象的,在定义bean的时候,由abstract属性设置,抽象的BeanDefition在getBean时会抛出异常
private boolean abstractFlag = false; //是否延迟加载
private boolean lazyInit = false; private int autowireMode = AUTOWIRE_NO; private int dependencyCheck = DEPENDENCY_CHECK_NONE; //依赖关系,在定义bean的时候,由depend-on属性设置,被依赖的bean在该bean之前被容器初始化
private String[] dependsOn; private boolean autowireCandidate = true; private boolean primary = false; private final Map<String, AutowireCandidateQualifier> qualifiers =
new LinkedHashMap<String, AutowireCandidateQualifier>(0); //是都允许访问非共有的属性
private boolean nonPublicAccessAllowed = true; //调用构造函数时,是否采用宽松匹配
private boolean lenientConstructorResolution = true; //工厂类Bean的名字
private String factoryBeanName; //工厂方法的名字
private String factoryMethodName; //构造函数参数的封装
private ConstructorArgumentValues constructorArgumentValues; //在定义bean时,property标签设置的属性
private MutablePropertyValues propertyValues; //跟Bean定义时的look-up有关
private MethodOverrides methodOverrides = new MethodOverrides(); //指定init方法名称,会在初始化的时候被调用
private String initMethodName; //指定destroy方法名称,会在被销毁时调用
private String destroyMethodName; private boolean enforceInitMethod = true; private boolean enforceDestroyMethod = true; //表示该Bean是否是由程序生成的
private boolean synthetic = false; private int role = BeanDefinition.ROLE_APPLICATION; private String description; private Resource resource; protected AbstractBeanDefinition() {
this(null, null);
} protected AbstractBeanDefinition(ConstructorArgumentValues cargs, MutablePropertyValues pvs) {
setConstructorArgumentValues(cargs);
setPropertyValues(pvs);
} //深拷贝
protected AbstractBeanDefinition(BeanDefinition original) {
setParentName(original.getParentName());
setBeanClassName(original.getBeanClassName());
setScope(original.getScope());
setAbstract(original.isAbstract());
setLazyInit(original.isLazyInit());
setFactoryBeanName(original.getFactoryBeanName());
setFactoryMethodName(original.getFactoryMethodName());
setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
setRole(original.getRole());
setSource(original.getSource());
copyAttributesFrom(original); if (original instanceof AbstractBeanDefinition) {
AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
if (originalAbd.hasBeanClass()) {
setBeanClass(originalAbd.getBeanClass());
}
setAutowireMode(originalAbd.getAutowireMode());
setDependencyCheck(originalAbd.getDependencyCheck());
setDependsOn(originalAbd.getDependsOn());
setAutowireCandidate(originalAbd.isAutowireCandidate());
setPrimary(originalAbd.isPrimary());
copyQualifiersFrom(originalAbd);
setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
setInitMethodName(originalAbd.getInitMethodName());
setEnforceInitMethod(originalAbd.isEnforceInitMethod());
setDestroyMethodName(originalAbd.getDestroyMethodName());
setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
setSynthetic(originalAbd.isSynthetic());
setResource(originalAbd.getResource());
}
else {
setResourceDescription(original.getResourceDescription());
}
} //由其他BeanDefinition的值来覆盖自身的值
public void overrideFrom(BeanDefinition other) {
if (StringUtils.hasLength(other.getBeanClassName())) {
setBeanClassName(other.getBeanClassName());
}
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
setAbstract(other.isAbstract());
setLazyInit(other.isLazyInit());
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setRole(other.getRole());
setSource(other.getSource());
copyAttributesFrom(other); if (other instanceof AbstractBeanDefinition) {
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
if (otherAbd.hasBeanClass()) {
setBeanClass(otherAbd.getBeanClass());
}
setAutowireMode(otherAbd.getAutowireMode());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setPrimary(otherAbd.isPrimary());
copyQualifiersFrom(otherAbd);
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
if (StringUtils.hasLength(otherAbd.getInitMethodName())) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
}
else {
setResourceDescription(other.getResourceDescription());
}
} //根据默认设置来修改自身
public void applyDefaults(BeanDefinitionDefaults defaults) {
setLazyInit(defaults.isLazyInit());
setAutowireMode(defaults.getAutowireMode());
setDependencyCheck(defaults.getDependencyCheck());
setInitMethodName(defaults.getInitMethodName());
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());
setEnforceDestroyMethod(false);
} //设置bean的className
@Override
public void setBeanClassName(String beanClassName) {
this.beanClass = beanClassName;
} //获取这个Bean的className
@Override
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
//如果已经被解析成class,则通过class.getName方法返回class的名称
if (beanClassObject instanceof Class) {
return ((Class<?>) beanClassObject).getName();
}
else {
return (String) beanClassObject;
}
} //设置这个bean的class
public void setBeanClass(Class<?> beanClass) {
this.beanClass = beanClass;
} //返回这个bean的class,如果beanClass为空,未被解析,则会抛出异常
public Class<?> getBeanClass() throws IllegalStateException {
Object beanClassObject = this.beanClass;
if (beanClassObject == null) {
throw new IllegalStateException("No bean class specified on bean definition");
}
if (!(beanClassObject instanceof Class)) {
throw new IllegalStateException(
"Bean class name [" + beanClassObject + "] has not been resolved into an actual Class");
}
return (Class<?>) beanClassObject;
} //beanClass是否被解析成class
public boolean hasBeanClass() {
return (this.beanClass instanceof Class);
} //解析beanClass
public Class<?> resolveBeanClass(ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName();
if (className == null) {
return null;
}
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
} //设置bean的范围
@Override
public void setScope(String scope) {
this.scope = scope;
} //获取bean的返回
@Override
public String getScope() {
return this.scope;
} //是否是单例
@Override
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
} //是否是prototype
@Override
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(scope);
} public void setAbstract(boolean abstractFlag) {
this.abstractFlag = abstractFlag;
} @Override
public boolean isAbstract() {
return this.abstractFlag;
} @Override
public void setLazyInit(boolean lazyInit) {
this.lazyInit = lazyInit;
} @Override
public boolean isLazyInit() {
return this.lazyInit;
} public void setAutowireMode(int autowireMode) {
this.autowireMode = autowireMode;
} public int getAutowireMode() {
return this.autowireMode;
} //获取自动注入模式
public int getResolvedAutowireMode() {
//如果是自动检测,则根据构造函数来判断
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
// Work out whether to apply setter autowiring or constructor autowiring.
// If it has a no-arg constructor it's deemed to be setter autowiring,
// otherwise we'll try constructor autowiring.
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterTypes().length == 0) {
return AUTOWIRE_BY_TYPE;
}
}
return AUTOWIRE_CONSTRUCTOR;
}
else {
return this.autowireMode;
}
} public void setDependencyCheck(int dependencyCheck) {
this.dependencyCheck = dependencyCheck;
} public int getDependencyCheck() {
return this.dependencyCheck;
} @Override
public void setDependsOn(String... dependsOn) {
this.dependsOn = dependsOn;
} @Override
public String[] getDependsOn() {
return this.dependsOn;
} @Override
public void setAutowireCandidate(boolean autowireCandidate) {
this.autowireCandidate = autowireCandidate;
} @Override
public boolean isAutowireCandidate() {
return this.autowireCandidate;
} @Override
public void setPrimary(boolean primary) {
this.primary = primary;
} @Override
public boolean isPrimary() {
return this.primary;
} //自动注入时,用来增加其他限制
public void addQualifier(AutowireCandidateQualifier qualifier) {
this.qualifiers.put(qualifier.getTypeName(), qualifier);
} public boolean hasQualifier(String typeName) {
return this.qualifiers.keySet().contains(typeName);
} public AutowireCandidateQualifier getQualifier(String typeName) {
return this.qualifiers.get(typeName);
} public Set<AutowireCandidateQualifier> getQualifiers() {
return new LinkedHashSet<AutowireCandidateQualifier>(this.qualifiers.values());
} public void copyQualifiersFrom(AbstractBeanDefinition source) {
Assert.notNull(source, "Source must not be null");
this.qualifiers.putAll(source.qualifiers);
} public void setNonPublicAccessAllowed(boolean nonPublicAccessAllowed) {
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
} public boolean isNonPublicAccessAllowed() {
return this.nonPublicAccessAllowed;
} //构造器是否宽松匹配
public void setLenientConstructorResolution(boolean lenientConstructorResolution) {
this.lenientConstructorResolution = lenientConstructorResolution;
} public boolean isLenientConstructorResolution() {
return this.lenientConstructorResolution;
} //设置获取工厂Bean的Name
@Override
public void setFactoryBeanName(String factoryBeanName) {
this.factoryBeanName = factoryBeanName;
} @Override
public String getFactoryBeanName() {
return this.factoryBeanName;
} //设置工厂方法,通常用来实现单例模式
@Override
public void setFactoryMethodName(String factoryMethodName) {
this.factoryMethodName = factoryMethodName;
} @Override
public String getFactoryMethodName() {
return this.factoryMethodName;
} //设置构造函数参数
public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) {
this.constructorArgumentValues =
(constructorArgumentValues != null ? constructorArgumentValues : new ConstructorArgumentValues());
} @Override
public ConstructorArgumentValues getConstructorArgumentValues() {
return this.constructorArgumentValues;
} public boolean hasConstructorArgumentValues() {
return !this.constructorArgumentValues.isEmpty();
} //设置属性
public void setPropertyValues(MutablePropertyValues propertyValues) {
this.propertyValues = (propertyValues != null ? propertyValues : new MutablePropertyValues());
} @Override
public MutablePropertyValues getPropertyValues() {
return this.propertyValues;
} //方法注入
public void setMethodOverrides(MethodOverrides methodOverrides) {
this.methodOverrides = (methodOverrides != null ? methodOverrides : new MethodOverrides());
} public MethodOverrides getMethodOverrides() {
return this.methodOverrides;
} //设置init方法
public void setInitMethodName(String initMethodName) {
this.initMethodName = initMethodName;
} public String getInitMethodName() {
return this.initMethodName;
} public void setEnforceInitMethod(boolean enforceInitMethod) {
this.enforceInitMethod = enforceInitMethod;
} public boolean isEnforceInitMethod() {
return this.enforceInitMethod;
} //设置destory方法
public void setDestroyMethodName(String destroyMethodName) {
this.destroyMethodName = destroyMethodName;
} public String getDestroyMethodName() {
return this.destroyMethodName;
} public void setEnforceDestroyMethod(boolean enforceDestroyMethod) {
this.enforceDestroyMethod = enforceDestroyMethod;
} public boolean isEnforceDestroyMethod() {
return this.enforceDestroyMethod;
} //是否由代码生成
public void setSynthetic(boolean synthetic) {
this.synthetic = synthetic;
} public boolean isSynthetic() {
return this.synthetic;
} public void setRole(int role) {
this.role = role;
} @Override
public int getRole() {
return this.role;
} public void setDescription(String description) {
this.description = description;
} @Override
public String getDescription() {
return this.description;
} public void setResource(Resource resource) {
this.resource = resource;
} public Resource getResource() {
return this.resource;
} public void setResourceDescription(String resourceDescription) {
this.resource = new DescriptiveResource(resourceDescription);
} @Override
public String getResourceDescription() {
return (this.resource != null ? this.resource.getDescription() : null);
} public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
this.resource = new BeanDefinitionResource(originatingBd);
} @Override
public BeanDefinition getOriginatingBeanDefinition() {
return (this.resource instanceof BeanDefinitionResource ?
((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
} //校验
public void validate() throws BeanDefinitionValidationException {
//指定了工厂方法的bean,不能Y由methodOverriders。
//因为工厂方法已经指定了bean实例化的方法,CGLib在这种情况下无效
if (!getMethodOverrides().isEmpty() && getFactoryMethodName() != null) {
throw new BeanDefinitionValidationException(
"Cannot combine static factory method with method overrides: " +
"the static factory method must create the instance");
} if (hasBeanClass()) {
prepareMethodOverrides();
}
} public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
MethodOverrides methodOverrides = getMethodOverrides();
if (!methodOverrides.isEmpty()) {
Set<MethodOverride> overrides = methodOverrides.getOverrides();
synchronized (overrides) {
for (MethodOverride mo : overrides) {
prepareMethodOverride(mo);
}
}
}
} //确认这个重写的方法是否有被重载
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
else if (count == 1) {
//重载的值默认为true,
//API上说设置为false可以提高运行性能
mo.setOverloaded(false);
}
} @Override
public Object clone() {
return cloneBeanDefinition();
} public abstract AbstractBeanDefinition cloneBeanDefinition(); @Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AbstractBeanDefinition)) {
return false;
} AbstractBeanDefinition that = (AbstractBeanDefinition) other; if (!ObjectUtils.nullSafeEquals(getBeanClassName(), that.getBeanClassName())) return false;
if (!ObjectUtils.nullSafeEquals(this.scope, that.scope)) return false;
if (this.abstractFlag != that.abstractFlag) return false;
if (this.lazyInit != that.lazyInit) return false; if (this.autowireMode != that.autowireMode) return false;
if (this.dependencyCheck != that.dependencyCheck) return false;
if (!Arrays.equals(this.dependsOn, that.dependsOn)) return false;
if (this.autowireCandidate != that.autowireCandidate) return false;
if (!ObjectUtils.nullSafeEquals(this.qualifiers, that.qualifiers)) return false;
if (this.primary != that.primary) return false; if (this.nonPublicAccessAllowed != that.nonPublicAccessAllowed) return false;
if (this.lenientConstructorResolution != that.lenientConstructorResolution) return false;
if (!ObjectUtils.nullSafeEquals(this.constructorArgumentValues, that.constructorArgumentValues)) return false;
if (!ObjectUtils.nullSafeEquals(this.propertyValues, that.propertyValues)) return false;
if (!ObjectUtils.nullSafeEquals(this.methodOverrides, that.methodOverrides)) return false; if (!ObjectUtils.nullSafeEquals(this.factoryBeanName, that.factoryBeanName)) return false;
if (!ObjectUtils.nullSafeEquals(this.factoryMethodName, that.factoryMethodName)) return false;
if (!ObjectUtils.nullSafeEquals(this.initMethodName, that.initMethodName)) return false;
if (this.enforceInitMethod != that.enforceInitMethod) return false;
if (!ObjectUtils.nullSafeEquals(this.destroyMethodName, that.destroyMethodName)) return false;
if (this.enforceDestroyMethod != that.enforceDestroyMethod) return false; if (this.synthetic != that.synthetic) return false;
if (this.role != that.role) return false; return super.equals(other);
} @Override
public int hashCode() {
int hashCode = ObjectUtils.nullSafeHashCode(getBeanClassName());
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.scope);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.constructorArgumentValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.propertyValues);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryBeanName);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.factoryMethodName);
hashCode = 29 * hashCode + super.hashCode();
return hashCode;
} @Override
public String toString() {
StringBuilder sb = new StringBuilder("class [");
sb.append(getBeanClassName()).append("]");
sb.append("; scope=").append(this.scope);
sb.append("; abstract=").append(this.abstractFlag);
sb.append("; lazyInit=").append(this.lazyInit);
sb.append("; autowireMode=").append(this.autowireMode);
sb.append("; dependencyCheck=").append(this.dependencyCheck);
sb.append("; autowireCandidate=").append(this.autowireCandidate);
sb.append("; primary=").append(this.primary);
sb.append("; factoryBeanName=").append(this.factoryBeanName);
sb.append("; factoryMethodName=").append(this.factoryMethodName);
sb.append("; initMethodName=").append(this.initMethodName);
sb.append("; destroyMethodName=").append(this.destroyMethodName);
if (this.resource != null) {
sb.append("; defined in ").append(this.resource.getDescription());
}
return sb.toString();
} }

BeanDefinition源码解析的更多相关文章

  1. Spring组件BeanDefinition 源码解析

    BeanDefinition 继承图 继承的接口 BeanMetadataElement接口 将由承载配置源对象的bean元数据元素的类实现. 包含一个getSource的方法,可以获取到MetaDa ...

  2. springboot自动扫描添加的BeanDefinition源码解析

    1. springboot启动过程中,首先会收集需要加载的bean的定义,作为BeanDefinition对象,添加到BeanFactory中去. 由于BeanFactory中只有getBean之类获 ...

  3. springboot源码解析-管中窥豹系列之BeanDefinition(八)

    一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...

  4. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

  5. spring MVC cors跨域实现源码解析

    # spring MVC cors跨域实现源码解析 > 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就 ...

  6. spring事务源码解析

    前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...

  7. 【Spring源码分析】.properties文件读取及占位符${...}替换源码解析

    前言 我们在开发中常遇到一种场景,Bean里面有一些参数是比较固定的,这种时候通常会采用配置的方式,将这些参数配置在.properties文件中,然后在Bean实例化的时候通过Spring将这些.pr ...

  8. 异步任务spring @Async注解源码解析

    1.引子 开启异步任务使用方法: 1).方法上加@Async注解 2).启动类或者配置类上@EnableAsync 2.源码解析 虽然spring5已经出来了,但是我们还是使用的spring4,本文就 ...

  9. [spring源码] 小白级别的源码解析ioc(二)

    之前一篇,整体描述了一下 Spring的整体概况和 jar包的介绍. 现在开始进入具体的源码解析,从本篇开始,先介绍spring的ioc容器.之前也看过一些介绍spring源码的, 有的是只讲整体的接 ...

随机推荐

  1. mysql正则匹配中文时存在的问题

    可以看到,目前正则匹配字母没问题,c出现1次,2次,3次匹配的结果都是正常的 接下来我们看看匹配中文的效果 可以看到,当匹配连续出现歪时,结果就开始不正常了 然后我去看了下mysql的中文文档中关于正 ...

  2. JSP 简介(转载)

    什么是Java Server Pages? JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%> ...

  3. Shell:homework

    1.判断/etc/inittab文件是否大于100行,如果大于,则显示”/etc/inittab is a big file.”否则显示”/etc/inittab is a small file.”# ...

  4. 计算机网络协议,IPV4数据报分析

    一.IP数据报结构分析 1.整体结构 一个IP数据报由首部和数据两部分组成. 首部的前一部分固定长20字节,这是所有IP数据报必须具有的:在首部的固定部分后面是一些可选字段,其长度是可变的. IP数据 ...

  5. Array(数组)对象-->数组长度的获取以及增减

    1.数组长度的获取: 属性:length 用法:数组名.length 举例:求一个数组的长度 var arr = [1,2,3,4,5] var arr_length = arr.length con ...

  6. python3(十八)decorator

    # -----------------------1-------------------------------------------- # 由于函数也是一个对象,而且函数对象可以被赋值给变量,所 ...

  7. Java相同id的数据集合,合并数据为一条,并将几个字段内容合并为一个

    Java实现,当然也可以数据库实现; /** * Created by shaozhiqi on 2019/7/31. */ public class TestUnion { @Test public ...

  8. std::string::substr函数

    string substr (size_t pos = 0, size_t len = npos) const;

  9. 用Python绘制全球疫情变化地图

    目前全球疫情仍然比较严重,为了能清晰地看到疫情爆发以来至现在全球疫情的变化趋势,我绘制了一张疫情变化地图,完整代码共 230 行,需要的朋友在公众号回复关键字 疫情地图 即可. 废话不多说,先上图 下 ...

  10. work of 1/6/2016

    part 组员                今日工作              工作耗时/h 明日计划 工作耗时/h    UI 冯晓云 UI动态布局改进和攻克疑难     6 继续下滑条等增删补减 ...