05-SpringBoot自动配置-Enable注解原理
-
SpringBoot不能直接获取在其他工程中定义的Bean
演示代码:
springboot-enable工程
/**
* @ComponentScan 扫描范围:当前引导类所在包及其子包
*
* com.itheima.springbootenable
* com.itheima.config
* //1.使用@ComponentScan扫描com.itheima.config包
* //2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
* //3.可以对Import注解进行封装。
*/
//@ComponentScan("com.itheima.config")
//@Import(UserConfig.class)
@EnableUser
@SpringBootApplication
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
//获取Bean
Object user = context.getBean("user");
System.out.println(user);
}
}
pom中引入springboot-enable-other
<dependency>
<groupId>com.itheima</groupId>
<artifactId>springboot-enable-other</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
springboot-enable-other工程
UserConfig
@Configuration
public class UserConfig {
@Bean
public User user() {
return new User();
}
}
EnableUser注解类
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)
public @interface EnableUser {
}
原因:@ComponentScan 扫描范围:当前引导类所在包及其子包
三种解决方案:
1.使用@ComponentScan扫描com.itheima.config包
2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
3.可以对Import注解进行封装。
重点:Enable注解底层原理是使用@Import注解实现Bean的动态加载
06-SpringBoot自动配置-@Import详解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法:
①导入Bean
②导入配置类
③导入 ImportSelector 实现类。一般用于加载配置文件中的类
④导入 ImportBeanDefinitionRegistrar 实现类。
- 导入Bean @Import(User.class)
- 导入配置类 @Import(UserConfig.class)
- 导入 ImportSelector 实现类 @Import(MyImportSelector.class)
MyImportSelector
```java
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.itheima.domain.User", "com.itheima.domain.Role"};
}
}
-
导入 ImportBeanDefinitionRegistrar 实现类。@Import({MyImportBeanDefinitionRegistrar.class})
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); registry.registerBeanDefinition("user", beanDefinition); } }
``
SpringbootEnableApplication测试代码
/**
* Import4中用法:
* 1. 导入Bean
* 2. 导入配置类
* 3. 导入ImportSelector的实现类。
* 4. 导入ImportBeanDefinitionRegistrar实现类
*/
//@Import(User.class)
//@Import(UserConfig.class)
//@Import(MyImportSelector.class)
//@Import({MyImportBeanDefinitionRegistrar.class})
@SpringBootApplication
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
/*//获取Bean
Object user = context.getBean("user");
System.out.println(user);*/
/*User user = context.getBean(User.class);
System.out.println(user);
Role role = context.getBean(Role.class);
System.out.println(role);*/
/* Object user = context.getBean("user");
System.out.println(user);*/
Map<String, User> map = context.getBeansOfType(User.class);
System.out.println(map);
}
@EnableAutoConfiguration中使用的是第三种方式:@Import(AutoConfigurationImportSelector.class)