对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. Github 如何查看自己的 star 和 fork

    最近在 github 上看到偶尔有几个项目被 fork,心里也是挺开心的,但是查看项目的 fork 和 star,网上没有一个具体的教程,都是一个模板各种抄,本文就详细介绍如何查看. 查看 fork ...

  2. [SWPUCTF 2021 新生赛]include

    打开我们可以看到让我们传入一个file,会出现一串代码,我们去分析一下: 当看到ini_set("allow_url_include","on");设置为on, ...

  3. linux系统下,redis如何设置密码

    1.命令方式 首先查看下密码是否存在,发现并未设置为空. -bash-4.2# cd /usr/local/redis-6.2.6/src -bash-4.2# ./redis-cli 127.0.0 ...

  4. 开启安全功能 ES 集群就安全了吗?

    背景 经常跟 ES 打交道的朋友都知道,现在主流的 ES 集群安全方案是:RBAC + TLS for Internal + HTTPS . 作为终端用户一般只需要关心用户名和密码就行了.作为管理和运 ...

  5. WPS WORD EXCEL 不合并显示

    WPS WORD EXCEL 不合并显示 版本:WPS 12 , 下载时间约是2023 年. 1.在开始菜单里找到 WPS OFFICE - 配置工具 2.点击"高级(A)". 3 ...

  6. chrome edge CORS 允许跨域

    edge: edge://flags/#block-insecure-private-network-requests chrome: 在谷歌浏览器地址栏输入"chrome://flags/ ...

  7. Lecture5

    Smiling & Weeping ---- 在街上看到长得和你相似的人时 我心中的那股雀跃 请你至少同情一下吧 第五章 Git 内部原理 5.0 引言 本章相对独立,从底层出发带你了解Git ...

  8. 哈啰面试:说说Dubbo运行原理?

    Dubbo 是一款高性能.轻量级的开源 RPC(远程过程调用)框架,主要用于构建分布式服务和微服务架构.那 Dubbo 又是如何运行的呢?让我们一起来看. 1.核心组件 要说 Dubbo 运行流程就不 ...

  9. Django-CBV和跨域请求伪造

    1. django模式 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_l ...

  10. .NET周刊【6月第4期 2024-06-23】

    国内文章 C#.Net筑基-集合知识全解 https://www.cnblogs.com/anding/p/18229596 .Net中提供了数组.列表.字典等多种集合类型,分为泛型和非泛型集合.泛型 ...