都是 spring 支持的,@Import 我也是从 spring 的文章张直接复制出来的,那边文章详细解释了 bean 的方方面面,感兴趣可以去看
@Configuration、@Bean
相当于 spring 的配置文件,spring 在配置文件中可以配置 bean,用注解方式就是这样的
// 这个类也会作为一个 bean
@Configuration
public class MyConfig {
// 方法名就是 bean 唯一标识
@Bean
public User user(){
User user = new User();
user.setUsername("Marry");
user.setId(12345L);
return user;
}
}
要让代码有语义,这种方式可以配置 bean,但是 @Configuration 的语义是代替 spring 的配置文件,如果只是想单纯配置一个 bean 其实这种方式并不清晰
如果只是单纯想配置一个 bean 使用 @Component 方式会更好
@Component
@Component
public class User {
private Long id;
private String username;
// getter setter
}
@Service、@Repository、@Controller 也是注册 bean,但是语义上不同(和上面的 @Configuration 一样,虽然都已配置 bean,但是还是建议符合语义的去配置)
@Import
有三种用法,导入的 bean 的唯一 id 是类的权限定名
@Import(A.class) // 导入普通类
@Import(MyImportSelector.class) // 导入实现了 ImportSelector 的类
@Import(MyImportBeanDefinitionRegister.class) // 需实现 ImportBeanDefinitionRegistrar 接口
-
导入普通类
/** * 这是一个普通的类,没有任何注解 */ public class User { private String name; } /** * 直接使用 @Import 导入User类到IOC容器中 */ @Import(User.class) @SpringBootApplication public class SpringConfig { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(SpringConfig.class, args); // 这种方式由于未定义 Bean id 和 name, getBean 时只能用类的class去拿或者类的权限定名 User bean = run.getBean(User.class); System.out.println(bean); } }
-
导入实现了 ImportSelector 的类(能批量导入,原理是注册一批 BeanDefinition)
// 一个实现了 ImportSelector 接口的类 public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 参数 importingClassMetadata 可以获取当前类被 @Import 导入的类的所有注解信息(有点绕看下面) // 返回值是个数组,数组的每一项都会导入 ioc 容器 return new String[]{User.class.getName(), Order.class.getName()}; } } // importingClassMetadata 就是能获取这个类的所有注解信息,SpringBootConfiguration、EnableAutoConfiguration、ComponentScan 等 @Import(MyImportSelector.class) @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public class SpringConfig { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(SpringConfig.class, args); User bean = run.getBean(User.class); System.out.println(bean); } }
-
导入实现了 ImportBeanDefinitionRegistrar 的类
// 一个实现了 ImportBeanDefinitionRegistrar 接口的类 public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 创建一个 BeanDefinition AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); // 注册到 ioc 容器 registry.registerBeanDefinition("user", beanDefinition); } } @Import(User.class) @SpringBootApplication public class SpringConfig { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(SpringConfig.class, args); User bean = run.getBean(User.class); System.out.println(bean); } }
秀肌肉
// 定义一个注解,导入 MyBeanDefinitionRegister
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import(MyBeanDefinitionRegister.class)
public @interface CyrusScan{
}
// 定义 MyBeanDefinitionRegister
public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
registry.registerBeanDefinition("user", beanDefinition);
}
}
// 启动类或配置类使用自定义注解 CyrusScan,就会自动注册 User 类型的 bean
@SpringBootConfiguration
@CyrusScan
public class SpringConfig {
}
标签:run,springboot,class,bean,User,注册,Import,public
From: https://www.cnblogs.com/cryus/p/18285643