包扫描@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

比如,定义和注入配置文件映射类需要使用注解ConfigurationPropertiesEnableConfigurationProperties,那么当配置文件变多的时候,注入起来就比较麻烦了@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学习笔记(三)-常用注入组件方式的更多相关文章

  1. SpringBoot学习笔记(14)----应用监控-HTTP方式

    SpringBoot提供了三种应用监控的方式 通过HTTP(最简单方便) 通过JMX 通过远程shell 这里就是用最简单的方式来使用SpringBoot的应用监控 首先引入依赖,pom文件如下 &l ...

  2. IBatis.Net学习笔记五--常用的查询方式

    在项目开发过程中,查询占了很大的一个比重,一个框架的好坏也很多程度上取决于查询的灵活性和效率.在IBatis.Net中提供了方便的数据库查询方式. 在Dao代码部分主要有两种方式:1.查询结果为一个对 ...

  3. SpringBoot学习笔记三之表述层

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6803355920697917965/ 首先配置learn-admin-webui中的web.xml文件 配置Con ...

  4. Springboot学习笔记(六)-配置化注入

    前言 前面写过一个Springboot学习笔记(一)-线程池的简化及使用,发现有个缺陷,打个比方,我这个线程池写在一个公用服务中,各项参数都定死了,现在有两个服务要调用它,一个服务的线程数通常很多,而 ...

  5. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

  6. SpringBoot学习笔记(7):Druid使用心得

    SpringBoot学习笔记(7):Druid使用心得 快速开始 添加依赖 <dependency> <groupId>com.alibaba</groupId> ...

  7. Spring源码学习笔记9——构造器注入及其循环依赖

    Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...

  8. [Firefly引擎][学习笔记三][已完结]所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  9. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

随机推荐

  1. [HAOI2016]食物链

    OJ题号:BZOJ4562.洛谷3183 思路:记忆化搜索. 本体可以转化成“求有向图中入度为0的结点到出度为0的结点的路径数”. 每次加边时记录每个结点的入度和出度,然后从入度为0的结点开始搜索,搜 ...

  2. Spring 3.1 M1: Unified Property Management(转)

    In the first two posts of this series, I described the bean definition profiles feature, and how it ...

  3. 8-06. 畅通project之局部最小花费问题(35)(最小生成树_Prim)(ZJU_PAT)

    题目链接:http://pat.zju.edu.cn/contests/ds/8-06 某地区经过对城镇交通状况的调查.得到现有城镇间高速道路的统计数据,并提出"畅通project" ...

  4. Knockout.Js官网学习(checked 绑定)

    前言 checked绑定是关联到checkable的form表单控件到view model上 - 例如checkbox(<input type='checkbox'>)或者radio bu ...

  5. 第十八章 dubbo-monitor计数监控

    监控总体图: 红色:监控中心 -  dubbo-simple-monitor 黄色:provider 蓝色:consumer 统计总体流程: MonitorFilter向DubboMonitor发送数 ...

  6. Exception的ToString()方法究竟返回的是什么

    最近项目上线后遇到exception没有堆栈信息.所以跟踪一下 源码,其中主要的code如下: // Returns the stack trace as a string. If no stack ...

  7. iOS开发-适配器和外观模式

    适配器模式,属于结构型模式,其主要作用是将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.适配器模式有对象适配器和类适配器两种,类适配器模 ...

  8. 发布库到仓库 maven jcenter JitPack MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  9. Android GUI之Activity、Window、View

    相信大家在接触Android之初就已经知道了Activity中的setContentView方法的作用了,很明显此方法是用于为Activity填充相应的布局的.那么,Activity是如何将填充的布局 ...

  10. 回顾2018年最受欢迎的十四款NoSQL产品

    ​​虽然NoSQL的流行与火起来才短短一年的时间,但是不可否认,现在已经开始了第二代运动.尽管早期的堆栈代码只能算是一种实验,然而现在的系统已经更加的成熟.稳定.不过现在也面临着一个严酷的事实:技术越 ...