Spring注解驱动开发04(给容器中注册组件的方式)
给容器中注册组件的方式
1. 组件注解标注 + 包扫描(适用于自己写的类)
//控制层组件
@Controller
public class PersonController {
}
//业务逻辑层组件
@Service
public class PersonServic {
}
//持久层组件
@Repository
public class PersonDao {
}
//其他组件
@Component
public class Person {
}
包扫描(注解或者xml的方式)
1.使用注解的方式
@ComponentScan(value = "com.xxx")
2.使用xml的方式
<context:component-scan base-package="com.xxx"/>
2. @Bean(适用于第三方包里面的组件)
@Bean("组件id") 默认使用方法名作为id,返回值作为组件的类型
3. @Import(快速给容器中导入一个组件)
@Import的第一种用法
- 直接在配置类上加上注解@Import(要加入到ioc容器中的类的类模板)
@Configuration
@ComponentScan(value = "com.atguigu",excludeFilters = {
//不扫描@controller和service注解,type默认为注解类型,可以不写
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {Myfilter.class})})
@SuppressWarnings("all")
@Import(HashMap.class) //将HashMap类加入到ioc容器中
public class MainConfig {
}
可以看到@Import注解的value时个数组,所以也可以导入多个值
注意:@Import注入的bean默认id为类的全限定名
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
@Import(HashMap.class,TreeMap.class) //将HashMap类加入到ioc容器中
public class MainConfig {
}
- 编写测试类
@Test
public void testImport(){
try(ConfigurableApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class)) {
//查看容器中的所有对象
String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
- 查看打印结果
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
personController
personServic
java.util.HashMap //可以看到ioc容器中已经有hashmap
java.util.TreeMap //可以看到ioc容器中已经有treemap
person
p1
@Import的第二种用法:ImportSelector方式【重点】
这种方式的前提就是一个类要实现ImportSelector接口,假如我要用这种方法,目标对象是Myclass这个类,分析具体如下:
- 创建Myclass类并实现ImportSelector接口
//自定义逻辑返回需要导入的组件
public class MyClass implements ImportSelector {
/**
* @param importingClassMetadata 表示当前被@Import注解给标注的所有注解信息【不是重点】
* @return 就是我们实际上要导入到容器中的组件全类名【重点 】
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{
"java.util.LinkedHashSet",
"java.util.ArrayList"
};
}
}
- 在@Import注解上加入属性自定义类
@Import({HashMap.class, TreeMap.class, MyClass.class})
- 测试类
@Test
public void testImport(){
try(ConfigurableApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class)) {
System.out.println(ioc);
//查看容器中的所有对象
String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
- 查看打印结果

@Import的第三种用法:ImportBeanDefinitionRegistrar方式
同样是一个接口,类似于第二种ImportSelector用法,相似度80%,只不过这种用法比较自定义化注册,具体如下:
第一步:创建Myclass2类并实现ImportBeanDefinitionRegistrar接口
public class Myclass2 implements ImportBeanDefinitionRegistrar {
//该实现方法默认为空
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
}
}
参数分析:
- 第一个参数:annotationMetadata 和之前的ImportSelector参数一样都是表示当前被@Import注解给标注的所有注解信息
- 第二个参数表示用于注册定义一个bean
第二步:编写代码,自定义注册bean
public class Myclass2 implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//指定bean定义信息(包括bean的类型、作用域...)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class);
//注册一个bean指定bean名字(id)
beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition);
}
}
第三步:编写TestDemo 类,并标注上使用ImportBeanDefinitionRegistrar方式的Myclass2类
@Import({TestDemo2.class,Myclass.class,Myclass2.class})
public class TestDemo {
@Bean
public AccountDao2 accountDao222(){
return new AccountDao2();
}
}
第四步:运行结果
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
personController
personServic
java.util.HashMap
java.util.TreeMap
java.util.LinkedHashSet
java.util.ArrayList
person
p1
TestDemo4444 //可以看到已经在ioc中
4. @Import注解的三种使用方式总结
第一种用法:@Import({ 要导入的容器中的组件 } ):容器会自动注册这个组件,id默认是全类名
第二种用法:ImportSelector:返回需要导入的组件的全类名数组,springboot底层用的特别多【重点 】
第三种用法:ImportBeanDefinitionRegistrar:手动注册bean到容器
以上三种用法方式皆可混合在一个@Import中使用,特别注意第一种和第二种都是以全类名的方式注册,而第三中可自定义方式。
@Import注解本身在springboot中用的很多,特别是其中的第二种用法ImportSelector方式在springboot中使用的特别多,尤其要掌握!
Spring注解驱动开发04(给容器中注册组件的方式)的更多相关文章
- 【Spring注解驱动开发】使用@Import注解给容器中快速导入一个组件
写在前面 我们可以将一些bean组件交由Spring管理,并且Spring支持单实例bean和多实例bean.我们自己写的类,可以通过包扫描+标注注解(@Controller.@Servcie.@Re ...
- 【Spring注解驱动开发】在@Import注解中使用ImportBeanDefinitionRegistrar向容器中注册bean
写在前面 在前面的文章中,我们学习了如何使用@Import注解向Spring容器中导入bean,可以使用@Import注解快速向容器中导入bean,小伙伴们可以参见<[Spring注解驱动开发] ...
- 【Spring注解开发】组件注册-使用@Configuration和@Bean给容器中注册组件
写在前面 在之前的Spring版本中,我们只能通过写XML配置文件来定义我们的Bean,XML配置不仅繁琐,而且很容易出错,稍有不慎就会导致编写的应用程序各种报错,排查半天,发现是XML文件配置不对! ...
- 【Spring注解驱动开发】在@Import注解中使用ImportSelector接口导入bean
写在前面 在上一篇关于Spring的@Import注解的文章<[Spring注解驱动开发]使用@Import注解给容器中快速导入一个组件>中,我们简单介绍了如何使用@Import注解给容器 ...
- 【Spring注解驱动开发】面试官:如何将Service注入到Servlet中?朋友又栽了!!
写在前面 最近,一位读者出去面试前准备了很久,信心满满的去面试.没想到面试官的一个问题把他难住了.面试官的问题是这样的:如何使用Spring将Service注入到Servlet中呢?这位读者平时也是很 ...
- 0、Spring 注解驱动开发
0.Spring注解驱动开发 0.1 简介 <Spring注解驱动开发>是一套帮助我们深入了解Spring原理机制的教程: 现今SpringBoot.SpringCloud技术非常火热,作 ...
- 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!
写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...
- 【Spring注解驱动开发】组件注册-@ComponentScan-自动扫描组件&指定扫描规则
写在前面 在实际项目中,我们更多的是使用Spring的包扫描功能对项目中的包进行扫描,凡是在指定的包或子包中的类上标注了@Repository.@Service.@Controller.@Compon ...
- 【Spring注解驱动开发】自定义TypeFilter指定@ComponentScan注解的过滤规则
写在前面 Spring的强大之处不仅仅是提供了IOC容器,能够通过过滤规则指定排除和只包含哪些组件,它还能够通过自定义TypeFilter来指定过滤规则.如果Spring内置的过滤规则不能够满足我们的 ...
随机推荐
- 重学c#系列——c# 托管和非托管资源与代码相关(四)
前言 这是续第三节. 概况垃圾回收与我们写代码的关系: 强引用和弱引用 针对共享 Web 承载优化 垃圾回收和性能 应用程序域资源监视 正文 强引用和弱引用 垃圾回收器不能回收仍在引用的对象的内存-- ...
- Linux图形界面与命令行界面以及用户之间的转换
刚刚不小心进入了命令行界面,,,,,, ALT SHIFE F5 咋回去的呢 sudo startx 但是回去以后默认是root ,,,,,, 所以切换用户 su username//用户名 就可以切 ...
- ionic 侧边栏实例
侧边栏的使用范例: <body > <ion-side-menus> <!-- 中间内容 --> <ion-side-menu-content ng-cont ...
- 5.15 省选模拟赛 容斥 生成函数 dp
LINK:5.15 T2 个人感觉生成函数更无脑 容斥也好推的样子. 容易想到每次放数和数字的集合无关 所以得到一个dp f[i][j]表示前i个数字 逆序对为j的方案数. 容易得到转移 使用前缀和优 ...
- luogu P2183 [国家集训队]礼物
LINK:礼物 n个物品 m个人 每个人要分得wi 个物品 每个物品互异 分给每个人的物品不分顺序 求方案数. \(n,p\leq 1e9 m\leq 5\) 方案数 那显然是 第一个人拿了w1件物品 ...
- 【mysql数据库优化】
sql优化:1.MYSQL逻辑分层 :连接层 服务层 引擎层 存储层 InnoDB(默认) :事务优先 (适合高并发操作:行锁) MyISAM :性能优先 (表锁) 2.sql的执行顺序:SQL : ...
- TestFlight无法访问怎么办?TF如何链接AppStoreConnect解决教程
最近苹果商店半天下架近3万款应用的新闻闹的沸沸扬扬,很多被下架应用的运营商转将APP上架了TestFlight内测商店(TF签名上架),但是从7月31日起很多用户就开始反映TestFlight内测应用 ...
- Idea Live Temlpates 自定义代码
Idea Live Temlpates 自定义代码 目的 - 加快常用代码的书写 使用## 打开Settings 快捷键Ctrl+Alt+S 选中Live Templates 选中temlpates ...
- iOS CALayer 简单介绍
https://www.jianshu.com/p/09f4e36afd66 什么是CALayer: 总结:能看到的都是uiview,uiview能显示在屏幕上是因为它内部的一个层calyer层. 在 ...
- JVM进行篇
结合字节码指令理解Java虚拟机栈和栈帧 栈帧:每个栈帧对应一个被调用的方法,可以理解为一个方法的 ...