spring boot 加载原理

116 阅读2分钟

@Import注解使用详解

  • @Import注解的作用是什么 通过导入的方式,来实现把实例加入Spring容器中的功能,相当于Spring xml配置文件中的 标签。

  • @Import注解能够导入哪些类

  1. 可以导入普通类;
  2. 可以和@Configuration注解的类搭配使用;
  3. 可以和实现了ImportSelector和ImportBeanDefinitionRegistrar接口的类搭配使用。
  • @Import注解能够添加到哪些类上? @Import注解可以添加在自定义的注解、@SpringBootApplication(启动类)、@Configuration(配置类)和@Component(组件类)所注解的类上(@RestController、@Service、@Repository都属于@Component),从而实现将实例加入到Spring容器中的功能。

ImportSelector介绍

在@Configuration标注的Class上可以使用@Import引入其它的配置类,其实它还可以引入org.springframework.context.annotation.ImportSelector实现类。ImportSelector接口只定义了一个selectImports(),用于指定需要注册为bean的Class名称。当在@Configuration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把实现类中返回的Class名称都定义为bean。

通过其参数AnnotationMetadata importingClassMetadata可以获取到@Import标注的Class的各种信息,包括其Class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为Spring bean的Class名称

参考 blog.csdn.net/elim168/art…

  • 定义配置类
@Configuration
@ComponentScan("com.elim.spring.core.importselector")
@Import(HelloImportSelector.class)
public class HelloConfiguration {

    
}
  • ImportSelector 实现类
public class HelloImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //获取注解
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
        //
        String[] basePackages = (String[]) annotationAttributes.get("basePackages");
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
        scanner.addIncludeFilter(helloServiceFilter);
        Set<String> classes = new HashSet<>();
        for (String basePackage : basePackages) {
            scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));
        }
        //返回类全路径名
        return classes.toArray(new String[classes.size()]);
    }

}

Spring内置事件

1、ContextRefreshedEvent

ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用

2、ContextStartedEvent

当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序

3、ContextStoppedEvent

当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作

4、ContextClosedEvent

当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启

5、RequestHandledEvent

这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件