Springboot扫描包下被注解的类,把Bean注入容器

该项目为未导入其他框架的Springboot项目,所以只有Springboot的基本功能。项目结构目录如下:
在这里插入图片描述

  1. 创建configuration类
import com.michael.annotation.demo.POJO.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//1
@Configuration
//2
@ComponentScan(value = {"com.michael.annotation.demo.configuration","com.michael.annotation.demo.service"})
public class MyConfig {

    @Bean(name = "person02")
    public Person person01(){
        return new Person("Michael", 10);
    }

    @Bean(name = "person03")
    public Person person(){
        return new Person("Steven", 11);
    }
}
  • 代码1处注解表示这是一个configuration组件类
  • 代码2处为关键注解,指定要被扫描的包下的类,并且把组件类的实例注入到容器中。
  • 组件类可以是被@Service, @Repository, @Controller等注解所标识(注解)的类。我们可通过查看源码的方式检查元注解来判断注解的类型和特性。
  • @ComponentScan的value为数组类型,可以更加精细地指定要扫描的包。
  • 如果@ComponentScan的value只赋值为"com.michael"(扫描该包下的所有子包内被注解的类),启动项目将引发错误。因为@SpringBootApplication注解会自动扫描被注入容器,再次扫描将引发Exception。
Caused by: javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Admin,name=SpringApplication
  1. 以MyConfig类当做配置类,并且初始化配置。
import com.michael.annotation.demo.configuration.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        ApplicationContext applicationContext  =  new AnnotationConfigApplicationContext(MyConfig.class);
        //打印所有在容器中的实例(Bean)
        String [] beanNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames
        ) {
            System.out.println(beanName);

        }
    }

}

输出:

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
myConfig
personService
person02
person03
  1. 更加精细化地扫描,使用excludeFilters排除要扫描的类。
import com.michael.annotation.demo.POJO.Person;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
//1
@ComponentScan(value = {"com.michael"},
excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = SpringBootApplication.class)
})
public class MyConfig {

    @Bean(name = "person02")
    public Person person01(){
        return new Person("Michael", 10);
    }

    @Bean(name = "person03")
    public Person person(){
        return new Person("Steven", 11);
    }
}
  • 代码1处修改指定扫描的包为项目下所有包,并且添加要排除的类(这里可以其他规则排除)。注意,classes为数组类型。
    在这里插入图片描述
  • 启动项目,发现并没有报错。说明启动类没有被重复注入。
    输出:
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
myConfig
personService
person02
person03
  1. 更加精细化地扫描,使用includeFilters指定只要扫描的类。这里需要注意,需要把useDefaultFilters设置为false,这样就能把默认扫描规则全部禁止,再定义更为严格的只扫描哪些类的规则。
    在这里插入图片描述
  2. @ComponentScan 为可重复注解的注解,所以可以重复注解类去定义多个规则。
    在这里插入图片描述
  3. 或者使用@ComponentScans去替代多个@ComponentScan
    在这里插入图片描述
发布了70 篇原创文章 · 获赞 4 · 访问量 3043

猜你喜欢

转载自blog.csdn.net/qq_34515959/article/details/104981661