对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 补充学习的更多相关文章

  1. ArcGIS API for JavaScript 4.2学习笔记[31] (补充学习)Task类

    Task这个东西很有用,是AJS中用于解决各种乱七八糟任务的一个类.它有很多子类,有用于空间分析的,有用于空间查询的,等等. 这篇作为补充学习的第一篇,也是进阶学习的第一篇,我就改个写法. 我将使用思 ...

  2. 20145219 《Java程序设计》第01周学习总结

    20145219 <Java程序设计>第01周学习总结 教材学习内容总结 软件分类:系统软件(DOS.Windows.Linux等).应用软件(扫雷.QQ等) 人机交互方式:图形化界面.命 ...

  3. 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)

    [原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...

  4. SpringBoot中JPA的学习

    SpringBoot中JPA的学习 准备环境和项目配置 写一下学习JPA的过程,主要是结合之前SpringBoot + Vue的项目和网上的博客学习一下. 首先,需要配置一下maven文件,有这么两个 ...

  5. 快速体验Spring Boot了解使用、运行和打包 | SpringBoot 2.7.2学习系列

    SpringBoot 2.7.2 学习系列,本节内容快速体验Spring Boot,带大家了解它的基本使用.运行和打包. Spring Boot 基于 Spring 框架,底层离不开 IoC.AoP ...

  6. springboot 尚桂谷学习总结01

    ------springboot 技术入门------ 1.springboot 简介: 优点: 简化spring 应用开发的一个框架 整个spring技术栈的一个大整合 ------微服务----- ...

  7. Springboot简介01

    前言: spring是近几年java中最具有代表而且最为流行的框架,spring是基于aop和IOC的思想,在我们的项目中充当了一个粘合剂的作用,既可以成为对象工厂,来管理我们的controller. ...

  8. JDK1.8源码分析01之学习建议(可以延伸其他源码学习)

    序言:目前有个计划就是准备看一下源码,来提升自己的技术实力.同时现在好多面试官都喜欢问源码,问你是否读过JDK源码等等? 针对如何阅读源码,也请教了我的老师.下面就先来看看老师的回答,也许会有帮助呢. ...

  9. SpringBoot官方文档学习(三)配置文件、日志、国际化和JSON

    一.Profiles Spring配置文件提供了一种方法来隔离应用程序配置的各个部分,并使其仅在某些环境中可用.任何@Component.@Configuration或@ConfigurationPr ...

  10. SpringBoot官方文档学习(一)SpringApplication

    Springboot通过main方法启动,在许多情况下,委派给静态SpringApplication.run方法: public static void main(String[] args) { S ...

随机推荐

  1. vue3 函数式组件

    今天看vue3中文文档 看到函数式组件不太理解上面写的 然后自己写了一下才理解上面的自己记录一下 先在子组件里面写上 <script> // dynameic 组件 import { h ...

  2. 再谈中断机制(APIC)

    中断是硬件和软件交互的一种机制,可以说整个操作系统,整个架构都是由中断来驱动的.一个中断的起末会经历设备,中断控制器,CPU 三个阶段:设备产生中断信号,中断控制器翻译信号,CPU 来实际处理信号. ...

  3. C# yyyyMMddHHmmss 格式的日期转换

    C# yyyyMMddHHmmss 格式的日期转换 DateTime dtTimeEnd = DateTime.Now; if (!string.IsNullOrWhiteSpace(rspA.fin ...

  4. el-upload拍照上传多个文件报错 ERR_UPLOAD_FILE_CHANGED问题

    最近同事使用el-upload上传图片时出现一个问题,连续拍照多个图片的时候,循环调用接口上传会报错: ERR_UPLOAD_FILE_CHANGED,网上找了很多方案没有解决,下面是我自己的解决过程 ...

  5. Excel Wps 透视表去重计数方法

    Excel Wps 透视表去重计数方法 在处理表格,遇到处理根据某个列去重后统计数量,而不是仅仅统计数量.在网上查找资料,不确定EXCEL或者WPS某个版本可以支持该功能的实现. 折中的方案,分两步来 ...

  6. 未能加载文件或程序集“netstandard,Version=2.0.0.0, Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51”或它的某一个依赖项 解决

    未能加载文件或程序集"netstandard,Version=2.0.0.0, Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51"或它 ...

  7. 高通lk:配置与使用i2c

    高通lk:配置与使用i2c 以msm8909为例. 背景 在lk中要去驱动一个aw9523的ic来控制指示灯. 但是现在对应的i2c没有打开.因此需要进行处理. 步骤 找到I2C对应的ID与句柄 参考 ...

  8. 福利来了!MoneyPrinterPlus可以自动配置环境和自动运行了

    之前开源了MoneyPrinterPlus,可以实现批量混剪视频,一键生成视频和自动发布视频的功能. 但是经常会看到小伙伴在安装过程中遇到很多问题.所以这篇文章的目的就是告诉大家怎么使用MoneyPr ...

  9. debian12 创建本地harbor镜像库

    前言 harbor是一个docker/podman镜像管理库,可用于存储私人镜像.现将本人在debian12系统搭建harbor镜像库的过程记录下来,留作后续参考. 可以参考github harbor ...

  10. DASCTF X GFCTF 2024|四月开启第一局 [PWN]详解

    DASCTF X GFCTF 2024|四月开启第一局[PWN] wp(详解) 1.dynamic_but_static 题目保护情况 64位程序,没有开canary和pie保护,got表可改 64位 ...