spring-framework-4.2.x(源码分析01)(源码编译)
github源码链接:
配置构建仓库
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
url "https://repo.spring.io/plugins-release"
}
mavenLocal() //配置先从本地仓库寻找jar包,优先寻找上一个配置,找到不执行下面的配置
mavenCentral() //配置从中央仓库寻找
google() //第三方仓库
jcenter() //代码托管库:设置之后可以在项目中轻松引用jcenter上的开源项目
}
转换源码为eclipse工具导入
gradle cleanidea eclipse
编译报错处理
unknown property ‘classesDir’
Could not get unknown property ‘classesDir’ for main classes of type org.gradle.api.internal.tasks.DefaultSourceSetOutput.
问题描述:使用Gradle 5.6.4版本构建spring-framework-4.2.x源码,遇到上述错误。
问题解决:
1、将build.gradle中 sourceSets.main.output.classesDir 修改为
sourceSets.main.output.classesDirs
2、将spring-aspects模块中aspects.gradle中 output.classesDir 修改为
output.classesDirs
3、将spring-oxm模块中oxm.gradle中 output.classesDir 修改为
output.classesDirs
问题产生原因:
Gradle 5.x以上版本中代码变动
sourceSets.main.output.classesDir 修改为
sourceSets.main.output.classesDirs 了
‘sonar-runner’ not found
Plugin with id ‘sonar-runner’ not found.
maven { url "http://repo.springsource.org/plugins-release" }
propdeps-plugin、docbook-reference-plugin
Could not resolve org.springframework.build.gradle:propdeps-plugin:0.0.7
Could not resolve io.spring.gradle:docbook-reference-plugin:0.3.1.
server: Forbidden
搞不定搞不定换个版本Try
下载链接: spring-framework-v5.2.19.RELEASE.
由于spring版本与gradle版本不匹配将会导致各种问题。
spring-framework提供了编译对应的gradle版本,对应信息在一下文件中
~\spring-framework-5.2.19.RELEASE\gradle\wrapper\gradle-wrapper.properties
Could not find xxxxx 问题解决
gradlew.bat install
> Could not find io.spring.gradle:propdeps-plugin:0.0.7.
> Could not find io.spring.gradle:docbook-reference-plugin:0.3.1.
buildscript {
repositories {
mavenLocal()
mavenCentral()
maven{ url "https://repo.spring.io/libs-release" }
maven{ url "https://plugins.gradle.org/m2/" }
maven{ url "https://repo.springsource.org/plugins-release" }
maven{ url 'https://maven.aliyun.com/repository/spring-plugin' }
maven{ url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven{ url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven{ url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
}
dependencies {
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.2")
classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
classpath("ws.antonov.gradle.plugins:gradle-plugin-protobuf:0.9.1")
}
}
......
......
dependencies {
testCompile("junit:junit:${junitVersion}") {
exclude group:'org.hamcrest', module:'hamcrest-core'
}
......
......
}
= = = = = 分割线 = = = = =
public class GoodsService {
private String name;
public GoodsService() {
System.out.println("GoodsService无参构造方法");
}
public void print(){
System.out.println("GoodsService#printf方法");
}
}
public class App {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(GoodsService.class);
GoodsService bean = ac.getBean(GoodsService.class);
bean.print();
}
}
执行结果:
GoodsService无参构造方法
GoodsService#printf方法
整体解析:
AnnotationConfigApplicationContext可以输入包含Configuration、@Import(Xxxx.class)、普通类。
将各种配置类解析成Spring内部定义的BeanDefinition,并以 beanName为 key,BeanDefinition为 value 存储在DefaultListableBeanFactory 中的 beanDefinitionMap
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
将 beanName 存入 beanDefinitionNames中,
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
然后遍历 beanDefinitionNames 中的 beanName,进行 bean 的实例化并填充属性,在实例化的过程中,如果有依赖没有被实例化将先实例化其依赖,然后实例化本身,实例化完成后将实例存入单例 bean 的缓存中,当调用 getBean 方法时,到单例 bean 的缓存中查找,如果找到并经过转换后返回这个实例 (如 LoginResource 的实例),之后就可以直接使用了。