@Import注解使用详解
-
@Import注解的作用是什么 通过导入的方式,来实现把实例加入Spring容器中的功能,相当于Spring xml配置文件中的 标签。
-
@Import注解能够导入哪些类
- 可以导入普通类;
- 可以和@Configuration注解的类搭配使用;
- 可以和实现了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名称
- 定义配置类
@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处理用户请求结束后,系统会自动触发该事件