JavaWeb学习打卡-Day6-SpringBean管理、SpringBoot自动装配、Maven高级

Spring Bean 的管理

获取Bean
  • 默认情况下,Spring项目启动时,会把bean都创建好放在IOC容器中,如果想要主动获取这些bean,可以通过如下方式:

    • 根据name获取bean:Object getBean(String name)
    • 根据类型获取bean:<T> T getBean(Class<T> requiredType)
    • 根据name获取bean(带类型转换):<T> T getBean(String name, Class<T> requiredType)
    java 复制代码
    @Autowired
    private ApplicationContext applicationContext;//IOC容器对象
    
    @Test
    public void testGetBean(){
    	//根据bean的名称获取
    	DeptController bean1 =(DeptController) applicationContext.getBean("deptController");
    	System.out.println(bean1);
    	//根据bean的类型获取
    	DeptController bean2 = applicationContext.getBean(DeptController.class);
    	System.out.println(bean2);
    	//根据bean的名称及类型获取
    	DeptController bean3 = applicationContext.getBean("deptcontroller",Deptcontroller.class);
    	System.out.println(bean3);
    }
  • 上述所说的"Spring项目启动时,会把其中的bean都创建好"是主要针对于默认的单例非延迟加载的bean而言的,还会受到作用域及延迟初始化影响。

Bean作用域
  • Spring中bean支持5种作用域,后三种在web环境才生效:
    • singleton:容器内同名称的 bean 只有一个实例(单例)(默认)
    • prototype:每次使用该 bean 时会创建新的实例(非单例)
    • request:每个请求范围内会创建新的实例(web环境中,了解)
    • session:每个会话范围内会创建新的实例(web环境中,了解)
    • application:每个应用范围内会创建新的实例(web环境中,了解)
  • 配置 bean 的作用域:
    • 可以通过 @Scope 注解来配置作用域:@Scope("prototype")
    • xml 方式:<bean id="..." class="..." scope="singleton"></bean>
  • 注意:
    • 默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)。
    • prototype的bean,每一次使用该bean的时候都会创建一个新的实例。
    • 实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。
第三方Bean
  • 如果要管理的bean对象来自于第三方(不是自定义的),是无法用 @Component及衍生注解声明bean的,就需要用到 @Bean注解。

  • 若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过 @Configuration 注解声明一个配置类。

    java 复制代码
    @Configuration
    public class CommonConfig{
    	@Bean
    	public SAXReader saxReader(){
    		return new SAXReader();
    	}
    }
  • 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名

  • 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。

@Component 和 @Bean
  • 在 Java Spring 框架中,@Component@Bean 都用于将对象注册到 Spring 容器中,但它们的应用场景和实现方式有显著区别。

    维度 @Component @Bean
    作用对象 面向类 面向方法
    控制权 隐式控制:由 Spring 自动实例化和管理 Bean 显式控制:开发者通过方法逻辑完全控制 Bean 的创建过程
    Bean 名称 默认使用类名首字母小写(如 userService) 默认使用方法名,或通过 @Bean(name = "myBean") 指定
    依赖关系 自动扫描(需启用组件扫描 @ComponentScan) 显式定义在 @Configuration 类中,手动控制实例化逻辑
    使用场景 自己编写的类 注册第三方库的类

Spring Boot 配置优先级

  • 由低到高:
    • application.yaml(忽略)
    • application.yml
    • application.properties
    • java系统属性(-Dxxx=xxx)
    • 命令行参数(--xxx=xxx)

Spring Boot 自动装配原理

Spring Boot 的自动配置就是当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

自动装配方案
  • @ComponentScan 组件扫描(繁琐,不推荐)

    java 复制代码
    @ComponentScan({"com.example","com.itheima","com.alibaba","com.google","org.springframework","org.mybatis",...})
    @SpringBootApplication
    public class SpringbootWebconfig2Application{
    }
  • @lmport 导入。使用@lmport可以导入普通类、配置类、以及ImportSelector 接口实现类。导入的类会被Spring加载到IOC容器中。

    java 复制代码
    @Import({TokenParser.class, HeaderConfig.class})
    @SpringBootApplication
    public class SpringbootWebConfig2Application{
    }
  • @Enablexxx注解。该注解封装了@Import注解,方便,优雅。

Spring Boot 是如何实现自动装配的?
  • SpringBoot 的核心注解 @SpringBootApplication,该注解标注在SpringBoot工程引导类上。
    • @SpringBootConfiguration:允许在上下文中注册额外的 bean 或导入其他配置类,与@Configuration作用相同。
    • @ComponentScan:默认会扫描启动类所在的包及其子包下所有的类 ,可以自定义不扫描某些 bean。
    • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制,是实现自动化配置的核心注解
  • @EnableAutoConfiguration 只是一个简单的注解,底层封装了@Import(AutoConfigurationImportselector.class)注解。
    • 自动装配核心功能的实现实际是通过 AutoConfigurationImportSelector类。
    • AutoConfigurationImportSelector 类实现了 ImportSelector接口,也就实现了这个接口中的 selectImports方法,该方法主要用于获取所有符合条件的类的全限定类名,返回的String[]种这些类需要被加载到 IOC 容器中。
    • 具体读取META-INF/spring.factories,获取需要自动装配的所有配置类。
    • Spring Boot会根据@ConditionalOnXXX注解条件装配。

总结:Spring Boot 通过@EnableAutoConfiguration开启自动装配,通过 SpringFactoriesLoader 最终加载META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx包实现起步依赖。

Maven 高级

分模块开发
  • 将项目按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享。
  • 分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分。
Maven 继承
  • 概念:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。
  • 作用:可以将公共依赖定义在父工程中,从而简化依赖配置、统一管理依赖。
  • 实现:<parent>...</parent>
    • 创建 maven 模块 tlias-parent,该工程为父工程,设置打包方式pom(默认jar)。<packaging>pom</packaging> jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)。

      war:普通web程序打包,需要部署在外部的tomcat服务器中运行。

      pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理。

    • 在子工程的pom.xml文件中配置继承关系。 在子工程中配置了继承关系之后,其坐标中的groupId是可以省略的,因为会自动继承父工程的。

      relativePath标签指定父工程的pom文件的相对位置(如果不指定,将从本地仓库/远程仓库查找该工程)。

    • 在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。 若父子工程都配置了同一个依赖的不同版本,以子工程的为准。
版本锁定
  • 可以在父工程的pom文件中通过<dependencyManagement>来统一管理依赖版本。
  • 子工程引入依赖时,无需指定<version>版本号,父工程统一管理。变更依赖版本只需在父工程中统一变更。 <dependencies>是直接依赖,在父工程配置了依赖,子工程会直接继承下来。

    <dependencyanagement>是统一管理依赖版本,不会直接依赖,还需要在子工程中引入所需依赖(无需指定版本)。

  • 还可以通过自定义属性集中管理版本号。
Maven 聚合
  • 聚合:将多个模块组织成一个整体,同时进行项目的构建。

  • 聚合工程:一个不具有业务功能的"空"工程(有且仅有一个pom文件)。

  • 作用:快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)。

  • 实现:通过<modules>设置当前聚合工程所包含的子模块名称。聚合工程中所包含的模块在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关。

    xml 复制代码
    <modules>
    	<module>../tlias-pojo</module>
    	<module>../tlias-utils</module>
    	<module>../tlias-web-management</module>
    </modules>
Maven 继承与聚合
  • 作用:
    • 聚合用于快速构建项目。
    • 继承用于简化依赖配置、统一管理依赖。
  • 相同点:
    • 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中。
    • 聚合与继承均属于设计型模块,并无实际的模块内容。
  • 不同点:
    • 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些。
    • 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己。
相关推荐
小杜-coding23 分钟前
黑马点评day02(缓存)
java·spring boot·redis·后端·spring·maven·mybatis
zfj3211 小时前
用spring-boot-maven-plugin打包成单个jar有哪些缺点&优化方案
java·maven·jar·springboot
24白菜头2 小时前
CSS学习笔记
前端·javascript·css·笔记·学习
程序员小刚2 小时前
基于SpringBoot + Vue 的火车票订票系统
vue.js·spring boot·后端
hac13222 小时前
IDEA快速上手Maven项目:模板选择 + 多模块拆分
java·maven·intellij-idea
吃货界的硬件攻城狮2 小时前
【STM32 学习笔记】GPIO输入与输出
笔记·stm32·学习
Chef_Chen2 小时前
从0开始学习大模型--Day01--大模型是什么
学习
缘友一世2 小时前
深度学习系统学习系列【1】之基本知识
人工智能·深度学习·学习
fanTuanye3 小时前
【SpringBoot篇】详解短信验证码登录功能实现
spring boot·后端
冉佳驹3 小时前
C语言 ——— 函数
c语言·数据结构·学习·递归·函数·嵌套调用·链式访问