找回密码
 立即注册
查看: 31|回复: 0

8,Bean管理之Bean注册

[复制链接]

260

主题

6

精华

264

金币

技术维护QQ:515138

积分
569
发表于 2026-2-24 13:42:31 | 显示全部楼层 |阅读模式
注解
说明
位置
@Component
声明bean的基础注解
不属于以下三类时,用此注解
@Controller
@Component的衍生注解
标注在控制器类上
@Service
@Component的衍生注解
标注在业务类上
@Repository
@Component的衍生注解
标注在数据访问类上(由于与mybatis整合,用的少)

如果要注册的bean对象来自于第三方(不是自定义的),是无法用 @Component 及衍生注解声明bean的
@Bean
@Import

测试案例:
1.jpg

1,安装jar包到maven本地仓库脚本
  1. mvn install:install-file -Dfile=F:\common-pojo-1.0-SNAPSHOT.jar -DgroupId=cn.itcast -DartifactId=common-pojo -Dversion=1.0 -Dpackaging=jar
复制代码
如图所示:
2.png 1.png
2,导入jar包
1.png

以上准备工作就绪,下面我们使用@Bean 注册演示

1,启动类上添加
  1. package com.jinhei;
  2. import cn.itcast.pojo.Country;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.annotation.Bean;
  7. @SpringBootApplication
  8. public class Demo4Application {
  9.     public static void main(String[] args) {
  10.         // run()方法会把初始化好的容器返回给用户,用户拿到容器后,就可以从容器中获取组件了
  11.         ApplicationContext context = SpringApplication.run(Demo4Application.class, args);
  12.         // 获取bean对象
  13.         Country country = context.getBean(Country.class);
  14.         System.out.println(country);
  15.         System.out.println("启动成功");
  16.     }
  17.     // 注入Country对象
  18.     @Bean //将方法返回值交给Ioc容器管理,成为Ioc容器的bean对象
  19.     public Country country(){
  20.         return new Country("中国", "中国");
  21.     }
  22. }
复制代码
演示效果如图所示:
2.png
2.png

启动类里面添加,不建议

2,在配置类里面注册
3.png
代码如下:
  1. package com.jinhei.config;
  2. import cn.itcast.pojo.Country;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. @Configuration
  6. public class CommonConfig {
  7.         @Bean //将方法返回值交给Ioc容器管理,成为Ioc容器的bean对象
  8.         public Country country(){
  9.             return new Country("中国", "金黑");
  10.         }
  11. }
复制代码
运行结果如图:
4.png


细节:
对象默认名字为方法名,根据名字获取bean对象
  1. package com.jinhei;
  2. import cn.itcast.pojo.Country;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.annotation.Bean;
  7. @SpringBootApplication
  8. public class Demo4Application {
  9.     public static void main(String[] args) {
  10.         // run()方法会把初始化好的容器返回给用户,用户拿到容器后,就可以从容器中获取组件了
  11.         ApplicationContext context = SpringApplication.run(Demo4Application.class, args);
  12.         // 获取bean对象
  13.         Country country = context.getBean(Country.class);
  14.         System.out.println(country);
  15.         // 根据名字获取bean对象
  16.         System.out.println(context.getBean("province"));
  17.         System.out.println("启动成功");
  18.     }
  19.     // 第一种,启动类里面注册,注入Country对象
  20. /*    @Bean //将方法返回值交给Ioc容器管理,成为Ioc容器的bean对象
  21.     public Country country(){
  22.         return new Country("中国", "中国");
  23.     }*/
  24. }
复制代码
  1. package com.jinhei.config;
  2. import cn.itcast.pojo.Country;
  3. import cn.itcast.pojo.Province;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. public class CommonConfig {
  8.         @Bean //将方法返回值交给Ioc容器管理,成为Ioc容器的bean对象
  9.         public Country country(){
  10.             return new Country("中国", "金黑");
  11.         }
  12.         @Bean // 对象默认名字为方法名
  13.         public Province province(){
  14.             return new Province("上海", "东");
  15.         }
  16. }
复制代码
1.png
【细节】给Bean取个名字:@Bean("jinhei")

1.jpg
【细节】如果方法的内部需要使用到IOC容器中已经存在的Bean对象,那么只需要在方法上声明即可,spring会自动的注入
  1. package com.jinhei.config;
  2. import cn.itcast.pojo.Country;
  3. import cn.itcast.pojo.Province;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. public class CommonConfig {
  8.         @Bean //将方法返回值交给Ioc容器管理,成为Ioc容器的bean对象
  9.         public Country country(){
  10.             return new Country("中国", "金黑");
  11.         }
  12.         @Bean// 对象默认名字为方法名
  13.         //如果方法的内部需要使用到IOC容器中已经存在的Bean对象,那么只需要在方法上声明即可,spring会自动的注入
  14.         public Province province(Country country){
  15.             System.out.println(country);
  16.             return new Province("上海", "东");
  17.         }
  18. }
复制代码
2.jpg
另一种方法:@Import


导入 配置类
导入 ImportSelector 接口实现类
@EnableXxxx注解,封装@Import注解

1.jpg

【重要】不在启动类所在包或子包下,导入类,同时会自动执行Bean注册,相当于手动扫描
1.jpg

  1. @Import(CommonConfig.class)
复制代码

如果注入多个类,写法:

  1. @Import({CommonConfig.class,CommonConfig.class,CommonConfig.class})
复制代码


还有一种方法:导入 ImportSelector 接口实现类


2.jpg
1,创建类
  1. package com.jinhei.config;
  2. import org.springframework.context.annotation.ImportSelector;
  3. import org.springframework.core.type.AnnotationMetadata;
  4. public class CommonImportSelector implements ImportSelector {
  5.     @Override
  6.     public String[] selectImports(AnnotationMetadata importingClassMetadata) {
  7.         return new String[]{"com.jinhei.config.CommonConfig"};
  8.     }
  9. }
复制代码
2,启动类添加@Import(CommonImportSelector.class)
  1. package com.jinhei;
  2. import cn.itcast.pojo.Country;
  3. import com.jinhei.config.CommonImportSelector;
  4. import org.springframework.boot.SpringApplication;
  5. import org.springframework.boot.autoconfigure.SpringBootApplication;
  6. import org.springframework.context.ApplicationContext;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Import;
  9. @SpringBootApplication
  10. @Import(CommonImportSelector.class)
  11. public class Demo4Application {
  12.     public static void main(String[] args) {
  13.         // run()方法会把初始化好的容器返回给用户,用户拿到容器后,就可以从容器中获取组件了
  14.         ApplicationContext context = SpringApplication.run(Demo4Application.class, args);
  15.         // 获取bean对象
  16.         Country country = context.getBean(Country.class);
  17.         System.out.println(country);
  18.         // 根据名字获取bean对象
  19.         System.out.println(context.getBean("province"));
  20.         System.out.println("启动成功");
  21.     }
  22.     // 第一种,启动类里面注册,注入Country对象
  23. /*    @Bean //将方法返回值交给Ioc容器管理,成为Ioc容器的bean对象
  24.     public Country country(){
  25.         return new Country("中国", "中国");
  26.     }*/
  27. }
复制代码
运行结果:
1.png


优化代码,让程序更灵活,类放到配置里面:
  1. package com.jinhei.config;
  2. import org.springframework.context.annotation.ImportSelector;
  3. import org.springframework.core.type.AnnotationMetadata;
  4. import java.io.BufferedReader;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class CommonImportSelector implements ImportSelector {
  10.     @Override
  11.     public String[] selectImports(AnnotationMetadata importingClassMetadata) {
  12.         // 读取配置文件的内容,根据配置内容,返回需要导入的组件
  13.         List<String> imports = new ArrayList<>();
  14.       /*  这段代码的功能是通过类加载器获取名为 "common.imports" 的资源文件的输入流。具体来说:
  15.         1,CommonImportSelector.class.getClassLoader() 获取当前类的类加载器。
  16.         2,getResourceAsStream("common.imports") 通过类加载器查找并返回名为 "common.imports" 的资源文件的 InputStream,用于后续读取文件内容。
  17.           该方法常用于从 classpath 中加载配置文件或资源文件。*/
  18.         InputStream is = CommonImportSelector.class.getClassLoader().getResourceAsStream("common.imports");
  19.         /*这段代码的功能是将输入流 is 包装成一个带缓冲的字符读取器 BufferedReader,以便高效地逐行读取文件内容。具体步骤如下:
  20.         1,使用 InputStreamReader 将字节流 is 转换为字符流。
  21.         2,用 BufferedReader 包装字符流,提供缓冲功能,提升读取效率。
  22.         3,后续可通过 br.readLine() 逐行读取文件内容。*/
  23.         BufferedReader br = new BufferedReader(new InputStreamReader(is));
  24.         String line = null;
  25.         try {
  26.             while ((line = br.readLine()) != null) {
  27.                 imports.add(line);
  28.             }
  29.         } catch (Exception e) {
  30.             e.printStackTrace();
  31.         }finally {
  32.             if (br != null) {
  33.                 try {
  34.                     br.close();
  35.                 } catch (Exception e) {
  36.                     e.printStackTrace();
  37.                 }
  38.             }
  39.         }
  40.         // 这段代码的功能是将 List<String> 类型的 imports 集合转换为字符串数组并返回。
  41.         // 返回需要导入的组件,字符串数组
  42.         /*具体说明:
  43.         1,imports.toArray(new String[0]):调用 List 的 toArray 方法,将集合中的元素转为 String 类型的数组。
  44.         2,new String[0]:提供一个空数组作为参数,确保返回的数组类型为 String[]。
  45.         3,返回结果:供 Spring 容器识别并导入指定的组件类。*/
  46.         return imports.toArray(new String[0]);
  47.     }
  48. }
复制代码

Ctrl+Alt+T,快捷键
try {
    while ((line = br.readLine()) != null) {
        imports.add(line);
    }
} catch (Exception e) {
    e.printStackTrace();
}


再优化注解
1,添加注解
  1. package com.jinhei.anno;
  2. import com.jinhei.config.CommonImportSelector;
  3. import org.springframework.context.annotation.Import;
  4. import java.lang.annotation.ElementType;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. @Target({ElementType.TYPE})
  9. @Retention(RetentionPolicy.RUNTIME)
  10. @Import(CommonImportSelector.class)
  11. public @interface EnableCommonConfig {
  12. }
复制代码
1.jpg

2,启动类添加注解@EnableCommonConfig
2.jpg

demo4.zip (24.46 KB, 下载次数: 1, 售价: 50 金币)




上一篇:7,Bean管理之Bean扫描
下一篇:9,SpringBoot3注册条件
网站建设,公众号小程序开发,系统定制,软件App开发,技术维护【联系我们】手机/微信:17817817816 QQ:515138

QQ|Archiver|自丢网 ( 粤ICP备2024252464号-1 )

GMT+8, 2026-3-5 17:59

专注于网站建设,公众号小程序制作,商城小程序,系统定制,软件App开发

【联系我们】手机/微信:17817817816 QQ:515138

快速回复 返回顶部 返回列表