ComponetScan 定义扫描规则

  1. value:指定要扫描的包
  2. excludeFilters=Filter[] 指定扫描的时候按照什么规则排除哪些组件。
  3. includeFilters=Filter[] 指定扫描的时候只需要包含哪些组件。(注意的是包扫描默认的是扫描所有的,也就是use-default-filters=”true”,所以需要设置为false。 这个和配置文件一样)
  • FilterType.ANNOTATION :按照注解的方式
  • FilterType.ASSIGNABLE_TYPE:按照给定的类型
  • FilterType.CUSTOM:使用自定义规则。 使用这个需要是TypeFilter的实现类
  • FilterType.CUSTOM使用 案例如下:
  • FilterType.ASPECTJ:使用ASPECTJ表达式(基本用不到)
  • FilterType.REGEX :使用正则表达式

例子

@Configuration
@ComponentScan(value = "feilong.example", useDefaultFilters = true, excludeFilters = {
//过滤掉具体的注解下所有类
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
// //过滤掉具体的类
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ConfigTest2.class})
},
//includeFilter里面的Filter是并集
includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
}
)
public class MainConfig { @Bean
public Person person() {
return new Person("feilong", 20);
}
}

类MyTypeFilter  是自定义Filter, 注意: 之前被过滤掉的类如果再自定义Filter中符合要求, 也会被重新放到IOC容器中.

public class MyTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取注解metaData
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
Resource resource = metadataReader.getResource(); //获取当前类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
String strClassName = classMetadata.getClassName(); System.out.println("通过自定义规则 ==>>>> " + strClassName); //返回true的类会被注册进IOC
return strClassName.contains("Controller"); }
}

@Import[快速的给容器中导入一个组件]

@Import的三种用法:

(1)、 @Import(要导入容器中的组件);容器中就会自动的注册这个组件,id默认是全类名
(2)、 ImportSelector :返回需要的组件的全类名的数组;
(3)、 ImportBeanDefinitionRegistrar : 手动注册bean到容器中

1. 组件注册-@Import-给容器中快速导入一个组件

定义两个POJO类

public class Color {
} public class Red {
}

将此类对应的Bean导入IOC容器

@Configuration
@ComponentScan(value = "feilong.example")
@Import({Color.class, Red.class})
public class MainConfig {
}

2. 使用ImportSelector

创建自定义MyImportSelector , 在方法selectImports 中返回要注入的类

public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"feilong.example.springbootlearn.Color","feilong.example.springbootlearn.Red"};
}
}

将自定义ImportSeletor加入配置文件

@Configuration
@ComponentScan(value = "feilong.example")
@Import(MyImportSelector.class)
public class MainConfig {
}

3. 使用 ImportBeanDefinitionRegistrar接口,

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("green", new RootBeanDefinition(Green.class));
}
}

将自定义ImportSeletor加入配置文件

@Configuration
@ComponentScan(value = "feilong.example")
@Import({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}

执行结果如下

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
feilong.example.springbootlearn.Color
feilong.example.springbootlearn.Red
person
person3
green

使用FactoryBean注解

创建自定义的一个FactoryBean

public class MyColorFactoryBean implements FactoryBean<Color> {
@Override
public Color getObject() throws Exception {
System.out.println("Creating Color Object by MyColorFactoryBean...");
return new Color();
} //控制是否为单例
// true:表示的就是一个单实例,在容器中保存一份
// false:多实例,每次获取都会创建一个新的bean
@Override
public boolean isSingleton() {
return true;
} @Override
public Class<?> getObjectType() {
return Color.class;
}
}

配置为Bean

@Configuration
@ComponentScan(value = "feilong.example")
public class MainConfig { @Bean
public Person person() {
return new Person("feilong", 20);
} @Bean("person3")
public Person personCondition() {
return new Person("feilong", 30);
} @Bean
public MyColorFactoryBean colorFactoryBean(){
return new MyColorFactoryBean();
}
}

测试

public class MainTest {
public static void main(String[] args) throws InterruptedException { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); String[] strName = ((AnnotationConfigApplicationContext) applicationContext).getBeanDefinitionNames(); for (String s : strName) {
System.out.println(s);
}     //此处获取的是getObject对象, 即Color对象
Color c = (Color) applicationContext.getBean("colorFactoryBean");
     //此处获取的是BeanFactory工厂对象本身
MyColorFactoryBean myColorFactoryBean =(MyColorFactoryBean) applicationContext.getBean("&colorFactoryBean");
System.out.println(c);
System.out.println(myColorFactoryBean);
}
} /*
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
person
person3
colorFactoryBean
Creating Color Object by MyColorFactoryBean...
feilong.example.springbootlearn.Color@2a32de6c
feilong.example.springbootlearn.MyColorFactoryBean@7692d9cc
*/

注意, 使用FactoryBean(工厂Bean) 默认获取到的是工厂Bean调用方法getObject()获取到的对象, 如果要想获取到原来的Bean工厂本身,需要加上&,


Bean生命周期

* 容器管理bean的生命周期:
  * 我们可以自定义初始化方法和销毁的方法:容器在bean进行到当前的生命周期的时候,来调用我们自定义的初始化方法和销毁方法
* 构造(对象创建):
  * 单实例:在容器启动的时候创建对象
  * 多实例:在每次获取的时候来创建对象
* 初始化方法:
  * 对象创建完成,并赋值好,调用初始化方法
* 销毁方法:
  * 单实例的bean:在容器关闭的时候进行销毁
  * 多实例的bean:容器不会管理这个bean,容器不会调用销毁的方法

生命周期-InitializingBeanDisposableBean

定义测试类:

public class CarLifeCycle implements InitializingBean {
public CarLifeCycle() {
System.out.println("CarLifeCycle constructor...");
} public void init() {
System.out.println("CarLifeCycle...init...");
} public void destroy() {
System.out.println("CarLifeCycle...destroy...");
} @Override
public void afterPropertiesSet() throws Exception {
System.out.println("接口 InitializingBean # afterPropertiesSet ");
}
}

定义MyBeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " => MyBeanPostProcessor .. before");
return bean;
} public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " => MyBeanPostProcessor .. after");
return bean;
}
}

注入IOC

@Configuration
@ComponentScan(value = "feilong.example")
public class MainConfig { @Bean(initMethod = "init")
public CarLifeCycle carLifeCycle(){
return new CarLifeCycle();
}
}

执行程序

CarLifeCycle constructor...
carLifeCycle => MyBeanPostProcessor .. before
接口 InitializingBean # afterPropertiesSet
CarLifeCycle...init...
carLifeCycle => MyBeanPostProcessor .. after

@ComponentScan比较的更多相关文章

  1. spring源码分析之<context:component-scan/>vs<annotation-config/>

    1.<context:annotation-config/> xsd中说明: <xsd:element name="annotation-config"> ...

  2. context:component-scan" 的前缀 "context" 未绑定。

    SpElUtilTest.testSpELLiteralExpressiontestSpELLiteralExpression(cn.zr.spring.spel.SpElUtilTest)org.s ...

  3. 为什么applicationContext.xml和spring-servlet.xml中都有注解过滤<context:component-scan base-package="myproject"> 和<context:component-scan base-package="myproject.controller" />

    在刚学习SpringMVC框架整合时,你也许会产生疑问为什么Spring.xml和SpringMVC.xml中都有注解过滤. <context:component-scan base-packa ...

  4. context:component-scan标签的use-default-filters属性的作用以及原理分析

    一.背景 我们在Spring+SpringMVC+Mybatis的集成开发中,经常会遇到事务配置不起作用等问题,那么本文就来分析下出现这种问题可能的原因以及解决方式. 二.分析及原理窥探 1.项目结构 ...

  5. spring <context:component-scan>使用说明(转)

    在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类 ...

  6. [转载]Difference between <context:annotation-config> vs <context:component-scan>

    在国外看到详细的说明一篇,非常浅显透彻.转给国内的筒子们:-) 原文标题: Spring中的<context:annotation-config>与<context:componen ...

  7. <context:component-scan>使用说明

    Spring组件扫描<context:component-scan/>使用详解 在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫 ...

  8. 关于context:component-scan配置中use-default-filters参数的作用

    参考了多篇文章都说明了use-default-filters参数的基本用途,但有些主要点没有说到,这里补充记录下: <context:component-scan base-package=&q ...

  9. annotation-config vs component-scan – Spring Core--转

    原文地址:http://techidiocy.com/annotation-config-vs-component-scan-spring-core/ <context:annotation-c ...

  10. context:component-scan扫描使用的use-default-filters

    如下方式可以成功扫描到@Controller注解的Bean,不会扫描@Service/@Repository的Bean. <context:component-scan base-package ...

随机推荐

  1. 七夕节来啦!AI一键生成情诗,去发给你的女朋友吧!

    [摘要] Hello大家好,今天就是七夕节了,为了增进和女朋友之间的情感,我写了一个自动生成情诗的AI: 大家可以在ModelArts尝试复现模型,然后快去发给你们的女朋友吧- 大家好,我是b站up主 ...

  2. 如何检查nofollow超链接属性是否有效

    http://www.wocaoseo.com/thread-88-1-1.html     nofollow 标签的重要性就不用阐述了,在这里武汉SEO与大家分享一些nofollow 标签的基本知识 ...

  3. py_正则表达式练习

    正则表达式: #正则表达式 #键盘数字6上的符号,^表示行的开始,$ 表示行的结束 #test = "tm queal Tomorrow Moon" ''' ^tm #匹配tm开头 ...

  4. 手写@Service、@Autowired、@Transactional注解,实现spring ioc和spring事务

    自定义@Service注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Custom ...

  5. 华师2019软件专硕复试机试题最后一题G:找数

    G. 找数 单点时限: 1.0 sec 内存限制: 256 MB 问题描述 输入一个整数 n( 2≤n≤10 ) ,你需要找到一些 n 位数(允许有前置 0 ,见样例),这些 n 位数均 由 0 ~ ...

  6. HTTPS的简介

    一.什么是HTTPS HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版.现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面. HTTPS主要作用是: (1) ...

  7. iOS打电话功能的简单实现

    小功能简介 iOS中的很多小功能都是非常简单的,几行代码就搞定了,比如打电话.打开网址.发邮件.发短信等 打电话-方法3 创建一个UIWebView来加载URL,拨完后能自动回到原应用 if (_we ...

  8. 使用powershell完成定时get任务

    最近公司网站需要在后台定时请求和更新数据,但PHP毕竟是一种后端语言,不能自动运行,所以整理了几个方法. 1.在前端定时请求页面. 2.使用批处理. 3.使用windows计划任务. 第一种方案必须要 ...

  9. BasicInterpreter1.00 运行简单Basic脚本 打印变量及字符串

    源码下载:https://files.cnblogs.com/files/heyang78/basicInterpreter-20200529-1.rar 脚本: count= print(count ...

  10. 转载:Linux: What’s the difference between a soft link and a hard link?

    Link:https://www.moreofless.co.uk/linux-difference-soft-symbolic-link-and-hard-link/ This example sh ...