对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. ajax传参

          // ajax传参         // ajax传参特点:         //   1,不需要跳转         //   2,ajax传参,都是异步程序         //    ...

  2. ETL工具-nifi干货系列 第十三讲 nifi处理器QueryDatabaseTable查询表数据实战教程

    1.处理器QueryDatabaseTable,该组件生成一个 SQL 查询,或者使用用户提供的语句,并执行它以获取所有在指定的最大值列中值大于先前所见最大值的行.查询结果将被转换为 Avro 格式, ...

  3. VMware搭建集群环境

    集群地址分配 名称 IP 子网掩码 网关 DNS flink01 192.168.22.211 255.255.255.0 192.168.22.2 114.114.114.114 flink02 1 ...

  4. INFINI Labs 产品更新 | Easysearch 1.8.2 发布优化 CCR 性能

    INFINI Labs 产品又更新啦~,包括 Easysearch v1.8.0.Gateway.Console.Agent.Loadgen v1.25.0.本次各产品更新了很多亮点功能,如 Easy ...

  5. Unity 3D 的NEW (堆内存)

    用容器装 在AWEKE NEW 运行时NEW 会导致分配内存时界面卡住, new class 的时候 才刷新程序帧 AWEKE 是程序启动时还没走完第一帧的开头执行 AWEKE 里面的代码 常量也在A ...

  6. python生成随机四位数和AttributeError: module 'random' has no attribute 'sample'

    python生成随机四位数和AttributeError: module 'random' has no attribute 'sample' ## AttributeError: module 'r ...

  7. http请求方式-CloseableHttpClient

    http请求方式-CloseableHttpClient import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObjec ...

  8. MySQL查询关于区分字母大小写问题

    前段时间在工作中测试提出了一个BUG,让我把根据ID查询区分大小写的功能去掉,大小写都随便查,然后我在SQL的位置加上了UPPER(id) = UPPER(#{id})的写法,而同事知道这个问题后的反 ...

  9. 探索Semantic Kernel内置插件:深入了解ConversationSummaryPlugin的应用

    前言 经过前几章的学习我们已经熟悉了Semantic Kernel 插件的概念,以及基于Prompts构造的Semantic Plugins和基于本地方法构建的Native Plugins.本章我们来 ...

  10. FTP传输PORT、PASV模式

    FTP FTP是File Transfer Protocol(文件传输协议)的缩写,用来在两台计算机之间互相传送文件.相比于HTTP,FTP协议要复杂得多.复杂的原因,是因为FTP协议要用到两个TCP ...