【SpringBoot】Re 01 补充学习
对SpringBoot后续的再补充学习:
使用IDEA创建项目不勾选任何组件
默认的POM结构:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.dai</groupId>
<artifactId>spirngboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spirngboot</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies> <!-- 运行核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<!-- 测试环境支持 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> <build>
<!-- 项目打包插件 -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
所谓的组件也就是一个个的组件坐标,我们可以自行配置。
这里的一些常用组件可以在IDEA初始化项目之后放POM里面:
<!-- 实体类简化辅助 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> <!-- MVC支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- 热部署与开发帮助支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency> <!-- 配置文件依赖提示支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
BeanDefinition对象
在之前的Spring理解是:
一个类ClassA.java注解了SpringBean,或者使用了Spring的XML配置,通过注解和XML配置的信息
我们就可以得到一个Bean对象,这个Bean对象由Spring管理和创建
但是现在不一样,这个实例是由BeanDefinition创建而来:
Bean定义对象存储了Bean对象的描述信息
OriginClass.java
|
BeanDefinition.java
|
BeanOriginClass.java
所在位置:
是一个接口,其实现类众多
org.springframework.beans.factory.config.BeanDefinition
属性:
String getParentName(); 父类名称
String getBeanClassName(); Bean的类名称
getScope(); 获取对象模式,单利还是原型
isLazyInit(); 是否懒加载
...
如何证明BeanDefinition创建
首先是一个类A,标注了Spring组件:
@Component
public class ClassA {
public ClassA() {
System.out.println("A实例被创建");
}
}
其次一个类B组合了类A也标注了组件
但是类A属性不自动装配:
@Component
public class ClassB { private ClassA classA; public ClassB() {
System.out.println("B实例被创建");
} public ClassA getClassA() {
return classA;
} public void setClassA(ClassA classA) {
this.classA = classA;
}
}
注册配置:
@Configurationpublic class TestConfiguration {
@Bean
public ClassB classB() {
return new ClassB();
}
@Bean
public ClassA classA() {
return new ClassA();
}
}
我们运行测试类很正常的发现在类B中的类A得到的是空
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
public class DefinitionTest { @Autowired
private ClassB classB; @Test
public void testSample() {
System.out.println(classB.getClassA());
}
}
结果:
B实例被创建
A实例被创建
null Process finished with exit code 0
我们可以通过定义对象去改变:
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// GenericBeanDefinition classAGenericBeanDefinition = (GenericBeanDefinition)configurableListableBeanFactory.getBeanDefinition("classB");
// classAGenericBeanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); RootBeanDefinition classARootBeanDefinition = (RootBeanDefinition)configurableListableBeanFactory.getBeanDefinition("classB");
classARootBeanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
}
}
配置类加载:
@Configuration
@Import(MyBeanFactoryPostProcessor.class)
public class TestConfiguration { @Bean
public ClassB classB() {
return new ClassB();
} @Bean
public ClassA classA() {
return new ClassA();
}
}
测试结果类A实例能够获取:
B实例被创建
A实例被创建。。。
cn.dzz.bean.ClassA@587e5365 Process finished with exit code 0
但是注意类B需要提供对应的GETTER & SETTER
在上面的定义修改中,Generic的实现类并不能被运行:
Caused by:
java.lang.ClassCastException:
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition
cannot be cast to org.springframework.beans.factory.support.GenericBeanDefinition
并不能强转为这个$ConfigurationClassBeanDefinition
所以需要查看下面有哪些子实现类

查看方式是点击这里:

Bean构造器参数值注入 ConstructorArgumentValues
这里有一个配置的问题,我们的类注册只能这样注解才能让定义处理器生效
就是让Spring以包扫描的方式进行
@Configuration
@ComponentScan("cn.dzz")
public class TestConfiguration {
}
不能以Import方式和@Bean配置类写方法的方式进行导入
类C的构造器声明:
@Component
public class ClassC { public ClassC() {
System.out.println("无参数");
} public ClassC(int i) {
System.out.println("一个整数参数");
} public ClassC(String i,int ii) {
System.out.println("一个字符参数,一个整数参数");
} }
构造器方法注入定义修改
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
GenericBeanDefinition classAGenericBeanDefinition = (GenericBeanDefinition)configurableListableBeanFactory.getBeanDefinition("classB");
classAGenericBeanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE); // RootBeanDefinition classARootBeanDefinition = (RootBeanDefinition)configurableListableBeanFactory.getBeanDefinition("classB");
// classARootBeanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME); // RootBeanDefinition classCRootBeanDefinition = (RootBeanDefinition)configurableListableBeanFactory.getBeanDefinition("classC");
// ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
// constructorArgumentValues.addIndexedArgumentValue(0,"哈哈哈");
// constructorArgumentValues.addIndexedArgumentValue(1,233);
// classCRootBeanDefinition.setConstructorArgumentValues(constructorArgumentValues); GenericBeanDefinition classCGenericBeanDefinition = (GenericBeanDefinition)configurableListableBeanFactory.getBeanDefinition("classC");
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0,"哈哈哈");
constructorArgumentValues.addIndexedArgumentValue(1,233);
classCGenericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);
}
}
测试结果:
A实例被创建
B实例被创建
一个字符参数,一个整数参数
cn.dzz.bean.ClassA@2638011 Process finished with exit code 0
Scope定义的修改
首先默认取两个对象测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
public class DefinitionTest { @Autowired
private ClassB classB; @Autowired
private ClassC classC01;
@Autowired
private ClassC classC02; @Test
public void testSample() {
System.out.println(classB.getClassA()); System.out.println(classC01 == classC02);
}
}
结果为True,因为我们知道Spring默认了Bean的Scope为单例Singleton
A实例被创建
B实例被创建
一个字符参数,一个整数参数
一个字符参数,一个整数参数
cn.dzz.bean.ClassA@117e949d
true Process finished with exit code 0
但是在上面的自定义的定义处理器更改Scope为原型模式之后则为False了
classCGenericBeanDefinition.setScope("prototype");
结果:
A实例被创建
B实例被创建
一个字符参数,一个整数参数
一个字符参数,一个整数参数
cn.dzz.bean.ClassA@117e949d
false Process finished with exit code 0
【SpringBoot】Re 01 补充学习的更多相关文章
- ArcGIS API for JavaScript 4.2学习笔记[31] (补充学习)Task类
Task这个东西很有用,是AJS中用于解决各种乱七八糟任务的一个类.它有很多子类,有用于空间分析的,有用于空间查询的,等等. 这篇作为补充学习的第一篇,也是进阶学习的第一篇,我就改个写法. 我将使用思 ...
- 20145219 《Java程序设计》第01周学习总结
20145219 <Java程序设计>第01周学习总结 教材学习内容总结 软件分类:系统软件(DOS.Windows.Linux等).应用软件(扫雷.QQ等) 人机交互方式:图形化界面.命 ...
- 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)
[原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...
- SpringBoot中JPA的学习
SpringBoot中JPA的学习 准备环境和项目配置 写一下学习JPA的过程,主要是结合之前SpringBoot + Vue的项目和网上的博客学习一下. 首先,需要配置一下maven文件,有这么两个 ...
- 快速体验Spring Boot了解使用、运行和打包 | SpringBoot 2.7.2学习系列
SpringBoot 2.7.2 学习系列,本节内容快速体验Spring Boot,带大家了解它的基本使用.运行和打包. Spring Boot 基于 Spring 框架,底层离不开 IoC.AoP ...
- springboot 尚桂谷学习总结01
------springboot 技术入门------ 1.springboot 简介: 优点: 简化spring 应用开发的一个框架 整个spring技术栈的一个大整合 ------微服务----- ...
- Springboot简介01
前言: spring是近几年java中最具有代表而且最为流行的框架,spring是基于aop和IOC的思想,在我们的项目中充当了一个粘合剂的作用,既可以成为对象工厂,来管理我们的controller. ...
- JDK1.8源码分析01之学习建议(可以延伸其他源码学习)
序言:目前有个计划就是准备看一下源码,来提升自己的技术实力.同时现在好多面试官都喜欢问源码,问你是否读过JDK源码等等? 针对如何阅读源码,也请教了我的老师.下面就先来看看老师的回答,也许会有帮助呢. ...
- SpringBoot官方文档学习(三)配置文件、日志、国际化和JSON
一.Profiles Spring配置文件提供了一种方法来隔离应用程序配置的各个部分,并使其仅在某些环境中可用.任何@Component.@Configuration或@ConfigurationPr ...
- SpringBoot官方文档学习(一)SpringApplication
Springboot通过main方法启动,在许多情况下,委派给静态SpringApplication.run方法: public static void main(String[] args) { S ...
随机推荐
- idea mapper xml 文件报红
在使用 idea 打开 mapper 文件,出现一下报红错误: 可以看到数据表和字段都是红色的. 解决方案 打开设置,window版本是打开Settings: 找到 Languages & F ...
- bpmnjs
在 bpmn.js 中,`bpmnModeler.get()` 方法用于获取不同的模块,你可以通过这些模块来访问和操作 BPMN 模型的不同部分.以下是一些常用的模块和对应的用途: 1. **Canv ...
- 使用Vulkan-Loader将ncnn代码改成Dynamic Loader Vulkan的形式
原本你写的程序是静态链接的系统的vulkan-1.dll,如果系统不存在vulkan-1.dll,则会直接崩溃. 关于将ncnn静态链接vulkan改成动态加载vulkan的形式,然后提供这两个函数 ...
- NCNN的内存显存分配器ncnn::Allocator & ncnn::VkAllocator翻译及其差异对比的学习笔记(nihui亲审过滴)
NCNN的内存分配器 ncnn::Allocator 通用内存分配器 ncnn::PoolAllocator 内存池分配器 可以设置池大小,减少分配内存和析构内存次数,空间换时间 ncnn:: ...
- 对于 EI K 逆序对排列计数的另一种自然求和方法的理解
有一个简单的 \(O(n^3)\) DP,考虑 \(f_{x + 1, k} = \sum_{j = 0}^{x} f_{x, k - j}\),利用前缀和优化即可. 考虑这实际上是 \(f_{x + ...
- tomcat部署Jenkins
安装环境 jdk 1.8 tomcat 9.0 jenkins 2.290 准备工作 安装好Tomcat,8080端口启动 安装好jdk,配置好环境变量 ECS服务器安全组放开8080端口 关闭防火墙 ...
- leetcode_2-两数相加_javascript
题目 2.两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新 ...
- MyBatis 关于查询语句上配置的详细内容
1. MyBatis 关于查询语句上配置的详细内容 @ 目录 1. MyBatis 关于查询语句上配置的详细内容 2. 准备工作 3. SQL查询结果,返回为POJO实体类型 4. SQL查询结果,返 ...
- LocalDateTime日期格式化和指定日期的时分秒
LocalDateTime日期格式化和指定日期的时分秒 package com.example.core.mydemo.date; import java.time.LocalDate; import ...
- 关于 "= default" 和 "= delete" 函数
在 C++ 11 中,"= default" 和 "= delete" 函数使我们能够显示指定成员函数是否自动生成. 其中,"= delete&quo ...