Springboot学习笔记(三)-常用注入组件方式
包扫描@ComponentScan
+组件标注注解(@Controller
、@Service
、@Repository
、@Component
)
包扫描不是必须的,指定包名后以指定的包名为准,比如指定包名为a:@ComponentScan("a")
,即使b包中有标注@Controller
等注解的bean也不注册。
包扫描注解除了默认的value()
还有basePackages()
、basePackageClasses()
等方法:
basePackages()
: 指定扫描的包名(前缀)
basePackageClasses()
:如果指定为A.class
,那么会扫描A类所在包的类。
includeFilters()
:将所指定的类注入容器。
excludeFilters()
:将所指定的类排除。
@ComponentScan.Filter
中的FilterType
除了给定的类型,还可以自定义:type=FilterType.CUSTOM
,指定的类实现TypeFilter
接口即可,同时注意不适用默认拦截器useDefaultFilters = false
。
比如,定义和注入配置文件映射类需要使用注解ConfigurationProperties
和EnableConfigurationProperties
,那么当配置文件变多的时候,注入起来就比较麻烦了@EnableConfigurationProperties(A.class, B.class, C.class...)
,所以可以使用自定义过滤器来注入所有的配置文件映射类,思路很简单,只要标注注解ConfigurationProperties
就将其注入:
public class IncludePropertiesFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return metadataReader.getAnnotationMetadata().hasAnnotation(EnableConfigurationProperties.class.getName());
}
}
在主启动类上开启过滤规则:
@SpringBootApplication
@ComponentScan(useDefaultFilters = false, includeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM, classes = IncludePropertiesFilter.class))
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Bean
可以放在方法和注解上。
一般放在标有@Configuration
类中的方法上。如:
@Import
只能用在类上,最简单直观,将A注入:
虽然直观,但需要批量注入就有点麻烦,@Import
提供了高级功能:
ImportSelector
ImportSelector是个接口,它只有一个方法:
String[] selectImports(AnnotationMetadata importingClassMetadata);
返回值是需要注入的类型全类名,入参是指和@Import
并列的全部注解信息,比如有个实现类:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
if (importingClassMetadata.hasAnnotation(UsesJava8.class.getName())) {
return new String[]{A.class.getName()};
}
return new String[0];
}
}
表示只有@UsesJava8
和@Import
同时标注时才注入A,以下情况会生效:
@SpringBootApplication
@Import(MyImportSelector.class)
@UsesJava8
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar也是个接口,它只有一个方法:
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
简单实现如下:
public class MyImportSelector implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("IThreadPool", new RootBeanDefinition(A.class));
}
}
调用:
@SpringBootApplication
@Import(MyImportSelector.class)
@UsesJava8
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
注册工厂Bean
和普通Bean不一样,普通的是通过调用构造器,而工厂是实现FactoryBean泛型接口,泛型为真正类型,通过getObject方法获取实例:
@Configuration
public class MyConfiguration {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
// com.y.pojo.MyConfiguration$A
System.out.println(context.getBean("aFactoryBean").getClass().getName());
// com.y.pojo.MyConfiguration$AFactoryBean
System.out.println(context.getBean("&aFactoryBean").getClass().getName());
A a1 = context.getBean("aFactoryBean", A.class);
A a2 = context.getBean("aFactoryBean", A.class);
// false
System.out.println(Objects.equals(a1, a2));
}
@Bean
public AFactoryBean aFactoryBean() {
return new AFactoryBean();
}
private static class A {
}
private static class AFactoryBean implements FactoryBean<A> {
@Override
public A getObject() throws Exception {
return new A();
}
@Override
public Class<?> getObjectType() {
return A.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
}
Springboot学习笔记(三)-常用注入组件方式的更多相关文章
- SpringBoot学习笔记(14)----应用监控-HTTP方式
SpringBoot提供了三种应用监控的方式 通过HTTP(最简单方便) 通过JMX 通过远程shell 这里就是用最简单的方式来使用SpringBoot的应用监控 首先引入依赖,pom文件如下 &l ...
- IBatis.Net学习笔记五--常用的查询方式
在项目开发过程中,查询占了很大的一个比重,一个框架的好坏也很多程度上取决于查询的灵活性和效率.在IBatis.Net中提供了方便的数据库查询方式. 在Dao代码部分主要有两种方式:1.查询结果为一个对 ...
- SpringBoot学习笔记三之表述层
注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6803355920697917965/ 首先配置learn-admin-webui中的web.xml文件 配置Con ...
- Springboot学习笔记(六)-配置化注入
前言 前面写过一个Springboot学习笔记(一)-线程池的简化及使用,发现有个缺陷,打个比方,我这个线程池写在一个公用服务中,各项参数都定死了,现在有两个服务要调用它,一个服务的线程数通常很多,而 ...
- C#学习笔记——面向对象、面向组件以及类型基础
C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...
- SpringBoot学习笔记(7):Druid使用心得
SpringBoot学习笔记(7):Druid使用心得 快速开始 添加依赖 <dependency> <groupId>com.alibaba</groupId> ...
- Spring源码学习笔记9——构造器注入及其循环依赖
Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- VSTO学习笔记(三) 开发Office 2010 64位COM加载项
原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...
随机推荐
- Java并发程序设计(十一)设计模式与并发之生产者-消费者模式
设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案.在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程. ...
- android TextView如何换行?
具体代码是: rb_zuotian.setText("第一行"+"\n"+"第二行"); rb_jintian.setText(DateUt ...
- 老菜鸟学习:Javascript 将html转成pdf
起因:处理某个项目,需要把页面上的数据(订单.运单)等导出pdf. 第一个想法:从 Java 层去想.但是经过各种资料查询和实践,第一个想法宣告放弃: 幸好客户的要求是:导出的 pdf 尺寸要和打印的 ...
- iOS web view 与 js 交互
移动应用中许多复杂的且经常改动的页面会使用H5进行代替native,这里就会使用到js和webview的交互 iOS里面,UIWebView提供了方法stringByEvaluatingJavaScr ...
- python: 序列化/反序列化及对象的深拷贝/浅拷贝
一.序列化/反序列化 python中内置了很多序列化/反序列化的方式,最常用的有json.pickle.marshal这三种,示例用法如下: import json import pickle imp ...
- Java知识回顾 (6)正则表达式、方法、文件与异常
一.正则表达式 正则表达式定义了字符串的模式. 正则表达式可以用来搜索.编辑或处理文本. 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别. Java 正则表达式和 Perl 的是最为相似 ...
- 版本视图找不到数据 EDITIONING VIEW
Oracle database 12 以后的版本,特别在EBS R12.2.X加入了版本视图这种技术,跟MOAC有点像. CREATE OR REPLACE FORCE EDITIONING VIEW ...
- selenium之关于 chromedriver的安装和使用
转自:https://blog.csdn.net/d77808675/article/details/79016271 最近在学习爬虫,用到了selenium 环境:Windows,python3 但 ...
- C# 获取文件名及扩展名【转】
https://www.cnblogs.com/libushuang/p/5794976.html C# 获取文件名及扩展名 string aFirstName = aFile.Substring(a ...
- 【H5动画】谈谈canvas动画的闪烁问题
一般来说,在H5开发中,使用canvas往往只是为了展示一些简单的图表或者简单短小的动画,很少考虑到有闪烁的问题. 最近,在手机QQ魔法表情的项目中,就遇到了奇葩的闪烁问题. 这里说的闪烁,是指动画刚 ...