SpringBoot 第二篇 之 @Component ,@ComponentScan 详解

本文详细探讨了SpringBoot中用于组件扫描的@Component和@ComponentScan注解。@Component标记类加入Spring IoC容器,而@ComponentScan指定扫描策略,包括默认扫描当前包及子包、自定义包名、过滤条件等。文中通过源码分析和示例代码展示了其工作原理和使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个个Bean使用@Bean注解注入Spring IoC 很麻烦,好在Spring允许我们进行扫描装配Bean

到IoC容器中,对于扫描装配而言使用的注解是 @Component 和@ComponentScan。

@Component 是标注哪个类被扫描进入 Spring IoC 容器,

@ComponentScan 则是标明采用何种策略去扫描装配Bean。

默认 @ComponentScan 只会扫描当前包和子包

@ComponentScan 源码如下:


  // IntelliJ API Decompiler stub source generated from a class file
  // Implementation of methods is not available

package org.springframework.context.annotation;

@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE})
@java.lang.annotation.Documented
public @interface ComponentScan {
    
       //定义扫描的包
    @org.springframework.core.annotation.AliasFor("basePackages")
    java.lang.String[] value() default {};

    // 定义扫描的包
    @org.springframework.core.annotation.AliasFor("value")
    java.lang.String[] basePackages() default {};
 
    //定义扫描的类
    java.lang.Class<?>[] basePackageClasses() default {};


        //bean 的name生成器
    java.lang.Class<? extends org.springframework.beans.factory.support.BeanNameGenerator> nameGenerator() default org.springframework.beans.factory.support.BeanNameGenerator.class;

    //作用域解析器
    java.lang.Class<? extends org.springframework.context.annotation.ScopeMetadataResolver> scopeResolver() default org.springframework.context.annotation.AnnotationScopeMetadataResolver.class;

    //作用域代理模式
    org.springframework.context.annotation.ScopedProxyMode scopedProxy() default org.springframework.context.annotation.ScopedProxyMode.DEFAULT;

    //资源匹配模式
    java.lang.String resourcePattern() default "**/*.class";

    //是否启用默认的过滤器
    boolean useDefaultFilters() default true;

    
    //当满足过滤器的条件时扫描
    org.springframework.context.annotation.ComponentScan.Filter[] includeFilters() default {};

    //当不满足过滤器的条件时扫描
    org.springframework.context.annotation.ComponentScan.Filter[] excludeFilters() default {};

    //是否延迟初始化
    boolean lazyInit() default false;

    //定义过滤器
    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
    @java.lang.annotation.Target({})
    static @interface Filter {
        org.springframework.context.annotation.FilterType type() default org.springframework.context.annotation.FilterType.ANNOTATION;

        @org.springframework.core.annotation.AliasFor("classes")
        java.lang.Class<?>[] value() default {};

        @org.springframework.core.annotation.AliasFor("value")
        java.lang.Class<?>[] classes() default {};

        java.lang.String[] pattern() default {};
    }
}

 

 

上面的代码中,首先可以通过配置项basePackages 定义扫描的包名,在没有定义的情况下

它只会扫描当前包和报下的路径;还可以通过basePackageClasses 定义 扫描的类;其中还有

includeFilters 和 excludeFilter ,includeFilter定义满足过滤器Filter条件的才去扫描,

excludeFilters则是排除过滤器的条件的Bean。他们都需要@Filter去定义。

它有一个type类型,可以定义为注解,或者正则等类型。classes定义注解类。

pattern定义正则类。

示例:

User.java

package com.didispace.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("iuser")
public class User {

    @Value("1")
    private Long id;

    @Value("user_name_1")
    private String userName;

    @Value("note_1")
    private String note;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}

AppConfig.java

package com.didispace.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;


//@Configuration 代表这时一个java配置文件,
// spring的 容器会根据它来生成IoC容器装配Bean
// @ComponentScan excludeFilers 排除使用@Service 的类
@Configuration
@ComponentScan(basePackages = { ”com.didispace.*” } ,
excludeFilters = {@Filter(classes = Service.class) ))
public class AppConfig {

}

IoCTest.java

package com.didispace;


import com.didispace.bean.User;
import com.didispace.config.AppConfig;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IoCTest {
    private static Logger log = Logger.getLogger(IoCTest.class);

    public static void main (String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        User user = ctx.getBean(User.class);
        log.info(user.getUserName());
    }
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值