@bean的理解(实质也是将第三方类库加入当前项目下的spring容器中)(使用@comment注解无法扫描因为不在同一包下)
1.作用与方法上
2.返回值是方法名(加入容器中的),可以修改
3.一般与@Configuration一起使用
@Configuration public class OSSConfig { /* * @Bean的作用 * 1.可以将返回值对象加入spring容器,对象别名默认就是方法名,还可以自定义别名@Bean("别名") * 2.方法参数对象可以从spring容器中获取对象注入 * */ @Bean public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties){ return new AliyunOSSOperator(aliyunOSSProperties); } } 类名:AliyunOSSOperator private AliyunOSSProperties aliyunOSSProperties; //1 publicAliyunOSSOperator(){}; publicAliyunOSSOperator(AliyunOSSProperties aliyunOSSProperties) {this.aliyunOSSProperties = aliyunOSSProperties; } 模拟第三方类库调用 理解:1.首先AliyunOSSProperties已经加入容器中了 2.通过调用AliyunOSSOperator类的有参构造器,参数因为已经加入容器,会隐式的调用注入, 3.通过返回值new出aliyunOSSOperator,加入spring boot容器,同时会给1中的aliyunOSSProperties赋值为传递过来的参数(即是容器中的aliyunOSSProperties对象)因此 1中aliyunOSSProperties相当于已经实例化定义了一个对象
扫描第三方类库
1. @ComponentScan({"com.itheima","com.example"}) 要写全,启动类所在的包也要写,因为未写扫描路径时默认扫描启动类及其子包,写了路径按指定的扫描
2.@EnableHeaderConfig 实际上时自定义注解,通过把@Import(MyImportSelector.class)等导入类聚合在一起了,然后添加注解(B包中要使用A包自定义的依赖要把A包的jar包导入B包的pom文件)不同项目下的注解
package com.itheima; import com.example.EnableHeaderConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //加载扫描Bean方案1: // @ComponentScan({"com.itheima","com.example"}) //加载扫描Bean方案2:@Import导入普通类 // @Import(HeaderParser.class) //加载扫描Bean方案2:@Import导入配置类 // @Import(HeaderConfig.class) //加载扫描Bean方案2:@Import导入 ImportSelector实现类 // @Import(MyImportSelector.class) @EnableHeaderConfig @SpringBootApplication public class SpringbootWebConfigApplication { public static void main(String[] args) { SpringApplication.run(SpringbootWebConfigApplication.class, args); } }
package com.example; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class HeaderConfig { //@ConditionalonClass:判断环境中是否有对应字节码文件,才注册bean到Ioc容器。 //@ConditionalOnClass(name="com.abc.Demo") //@ConditionalOnMissingBean 判断环境中没有对应的bean(类型 或 名称),才注册bean到Ioc容器。 // @ConditionalOnMissingBean //@ConditionalonProperty:判断配置文件中有对应属性和值,才注册bean到Ioc容器。 @ConditionalOnProperty(name="demo",havingValue = "abc") @Bean public HeaderParser headerParser1(){ return new HeaderParser(); } // @ConditionalOnMissingBean // @Bean // public HeaderParser headerParser2(){ // return new HeaderParser(); // } @Bean public HeaderGenerator headerGenerator(){ return new HeaderGenerator(); } }
@ConditionalOnClass 的核心作用是确保 Bean 注册的前提是 "依赖的类存在 所以对应的条件判断应该是所依赖的类
当@ConditionalOnMissingBean
未显式指定type
、value
或name
属性时,Spring 会默认以当前方法的返回类型作为匹配条件(类:类名,类名小驼峰 方法: 返回值类型,方法名)
同时指定type和那么name也不会存在重复,因为type判断返回值的类名,而name判断的则是类名的小驼峰
参数 |
指向目标 |
示例 |
type |
指定的 Class 类型(或其实现类、子类) |
类型的 Bean |
name |
指定名称的 Bean(无论其类型) |
的 Bean |
无参数 |
默认检查 当前方法返回类型 |
|
参数 |
指向目标 |
示例 |
type |
指定的 Class 类型(或其实现类、子类) |
类型的 Bean |
name |
指定名称的 Bean(无论其类型) |
的 Bean |
无参数 |
默认检查 类中所有 方法的返回类型 |
若类中有 和 两个 Bean 方法,则检查这两种类型是否存在 |
xml
<parent> <groupId>com.itheima</groupId> <artifactId>tlias-parent</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../tlias-parent/pom.xml</relativePath> </parent>
配置目的:
当本地项目结构里存在父子模块关系时,就需要借助相对路径来定位父模块的 POM 文件。就像这里的../tlias-parent/pom.xml
,意味着父模块的 POM 文件处于当前模块的上一级目录下的tlias-parent
目录中。
'
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.8</version> <relativePath/> <!-- lookup parent from repository --> </parent>
配置目的:
当使用像 Spring Boot Starter Parent 这类公共依赖时,就把<relativePath>
留空或者写成<relativePath/>
。这样做的意思是让 Maven 直接从本地仓库或者远程中央仓库去查找父 POM,而不是在本地项目结构里找。
针对依赖关系理解
继承关系(限定依赖的不用写版本号,可由父类指明) (子工程3 要使用1,2工程,直接导入工程依赖即可,调用方法不用在工程3中导入依赖)
1中的依赖,针对的是部分子类需要的,如果需要使用,就要显式的调用(即是:写出依赖)
2中的依赖,是针对所有的子类,不用显示表明直接从父类中继承(不用写)
子工程导入依赖是 “让代码能访问第三方库”(构建层面);
第三方 Bean 导入是 “让第三方类变成 Spring 组件”(框架层面),二者是 **“先用 Maven 引入代码依赖,再用 Spring 配置 Bean”** 的递进关系。