玩转Spring扫描创建bean

本文介绍了Spring如何通过@ComponentScan注解扫描包并创建bean,详细讲解了如何指定过滤规则,包括自定义注解、指定类、正则匹配和自定义过滤规则来决定bean的创建。同时,文章还探讨了includeFilters、excludeFilters和useDefaultFilters的使用,以及不同类型的过滤条件。
摘要由CSDN通过智能技术生成

Spring如何玩转扫描包?

当我们指定包名basePackages, 如@ComponentScan(basePackages = “cn.zhutan.myspringtest”), Spring会去加载该文件夹下面的class文件, 封装成MetadataReader元信息, 根据元信息判断哪些类需要创建bean, 哪些类不需要创建bean, 而这个判断条件, Spring提供了很强大的扩展, 有以下几种情况

  1. 根据贴上某注解判断创建或者不创建bean
  2. 指定某些类创建或者不创建bean
  3. 根据正则匹配哪些bean创建或者不创建
  4. 根据Aspectj判断bean的创建与否
  5. 根据用户写的规则判断bean的创建与否

Spring如何指定过滤规则?

在注解@ComponentScan中有几个核心属性

  1. includeFilters, 表示满足该过滤条件时, 要创建bean
  2. excludeFilters, 表示满足该过滤条件时, 不创建bean
  3. useDefaultFilters, 表示是否使用默认的过滤器, 默认是true, Spring内部则相当于在includeFilters加入了过滤规则, 即满足加了@Component的类会创建bean, 如果我们置为false, 即使我们加了@Component也不会创建bean
    查看注解@ComponentScan源码
@Retention(RetentionPolicy.RUNTIME)
@Target({
   ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
   
    // 省略其他...
    // 是否使用默认过滤器
    boolean useDefaultFilters() default true;
    // 满足条件要注入的bean
    ComponentScan.Filter[] includeFilters() default {
   };
    // 满足条件不注入的bean
    ComponentScan.Filter[] excludeFilters() default {
   };
    // 省略其他...
    @Retention(RetentionPolicy.RUNTIME)
    @Target({
   })
    public @interface Filter {
   
        FilterType type() default FilterType.ANNOTATION;
        @AliasFor("classes")
        Class<?>[] value() default {
   };
        @AliasFor("value")
        Class<?>[] classes() default {
   };
        String[] pattern() default {
   };
    }
}

includeFilters和excludeFilters需要参数为数组ComponentScan.Filter[], 表示可以配置多个过滤条件,
每个过滤条件都是ComponentScan.Filter对象, 而是过滤条件的种类是以type属性指定的

public enum FilterType {
   
   // 1. 根据贴上某注解判断创建或者不创建bean, 解析类AnnotationTypeFilter
   ANNOTATION,
   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring中,我们可以使用BeanFactory或者ApplicationContext来动态创建Bean实例。 1. 使用BeanFactory动态创建Bean实例 ```java DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Person.class); builder.addPropertyValue("name", "张三"); builder.addPropertyValue("age", 18); beanFactory.registerBeanDefinition("person", builder.getBeanDefinition()); Person person = (Person) beanFactory.getBean("person"); ``` 以上代码中,我们先创建一个DefaultListableBeanFactory实例,然后使用BeanDefinitionBuilder创建一个BeanDefinition,指定要创建Bean类型为Person,并设置Bean的属性值(name和age)。最后将BeanDefinition注册到BeanFactory中,然后通过getBean()方法获取动态创建的Person实例。 2. 使用ApplicationContext动态创建Bean实例 ```java GenericApplicationContext context = new GenericApplicationContext(); context.refresh(); GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(Person.class); beanDefinition.getPropertyValues().add("name", "张三"); beanDefinition.getPropertyValues().add("age", 18); context.registerBeanDefinition("person", beanDefinition); Person person = (Person) context.getBean("person"); ``` 以上代码中,我们创建了一个GenericApplicationContext实例,并调用refresh()方法初始化容器。然后创建一个GenericBeanDefinition实例,设置Bean的类型为Person,并设置Bean的属性值(name和age)。最后将BeanDefinition注册到ApplicationContext中,然后通过getBean()方法获取动态创建的Person实例。 总的来说,使用Spring动态创建Bean实例的方法比较灵活,可以根据具体的需求来选择使用BeanFactory或者ApplicationContext。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值