简介
本文用示例介绍SpringBoot如何向容器注册bean(即:将对象加入容器)。
法1:@Component
(@Controller/@Service/@Repository也可以,因为它里边包含@Component)
默认是加载和Application类所在同一个目录下的所有类,包括所有子目录下的类。
当启动类和@Component分开时,如果启动类在某个包下,需要在启动类中增加注解@ComponentScan,配置需要扫描的包名。例如:
@SpringBootApplication(scanBasePackages="com.test.chapter4")
此注解其实是@ComponentScan的basePackages,通过查看scanBasePackages即可得知。
@SpringBootApplication只会扫描@SpringBootApplication注解标记类包下及其子包的类,将这些类纳入到spring容器,只要类有@Component注解即可。
有的注解的定义中已加入@Component,所以这些注解也会被扫描到:@Controller,@Service,@Configuration,@Bean
@ComponentScan+@Configuration+@Component
DemoConfig在扫描路径之内
|
1 2 3 4 |
@Configuration @ComponentScan (basePackages = { "com.example.demo.mybeans" }) public class DemoConfig { } |
MyBean1在com.example.demo.mybeans下
|
1 2 3 |
@Component public class MyBean1{ } |
法2:@Configuration+@Bean
使用场景:将没有Component等注解的类导入。例如:第三方包里面的组件、将其他jar包中的类。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class User { //@Value("Tom") public String username;
public User(String s) { this .username = s; } }
@Configuration public class ImportConfig { @Bean public User user(){ return new User( "Lily" ); } }
@RestController public class ImportDemoController { @Autowired private User user;
@RequestMapping ( "/importDemo" ) public String demo() throws Exception { String s = user.username; return "ImportDemo@SpringBoot " + s; } } |
法3:@Import等
简介
@Import(要导入到容器中的组件);容器会自动注册这个组件,id默认是全类名。(@Import是Spring的注解。)
ImportSelector:返回需要导入的组件的全类名数组;
ImportBeanDefinitionRegistrar:手动注册bean到容器中
@Import方式
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
@Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) @Import ({ImportDemoConfig. class }) public @interface EnableImportDemo { }
public class ImportDemoConfig{ @Bean public User user(){ return new User( "Lily" ); } }
@EnableImportDemo @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication. class , args); } }
@RestController public class ImportDemoController { @Autowired private User user;
@RequestMapping ( "/importDemo" ) public String demo() { String s = user.getName(); return "user.getName():" + s; } } |
ImportSelector方式
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
//自定义逻辑返回需要导入的组件 public class MyImportSelector implements ImportSelector {
//返回值,就是到导入到容器中的组件全类名 //AnnotationMetadata:当前标注@Import注解的类的所有注解信息 @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { //当前类的所有注解 Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes(); System.out.println( "当前配置类的注解信息:" +annotationTypes); //注意不能返回null,不然会报NullPointException return new String[]{ "com.paopaoedu.springboot.bean.user01" , "com.paopaoedu.springboot.bean.user02" }; } }
public class User01 { public String username;
public User01() { System.out.println( "user01...constructor" ); } }
public class User02 { public String username;
public User02() { System.out.println( "user02...constructor" ); } }
@Configuration @Import ({ImportDemo. class , MyImportSelector. class }) public class ImportConfig { @Bean public User user(){ return new User( "Lily" ); } }
@RestController public class ImportDemoController { @Autowired private User user;
@Autowired private ImportDemo importDemo;
@Autowired private User01 user01;
@RequestMapping ( "/importDemo" ) public String demo() throws Exception { importDemo.doSomething(); user01.username = "user01" ; String s = user.username; String s1 = user01.username;
return "ImportDemo@SpringBoot " + s + " " + s1; } } |
ImportBeanDefinitionRegistrar方式
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** * AnnotationMetadata:当前类的注解信息 * BeanDefinitionRegistry:BeanDefinition注册类; * 把所有需要添加到容器中的bean;调用 * BeanDefinitionRegistry.registerBeanDefinition手工注册进来 */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition( "com.paopaoedu.springboot.bean.User01" ); boolean definition2 = registry.containsBeanDefinition( "com.paopaoedu.springboot.bean.User02" ); if (definition && definition2){ //指定Bean定义信息作用域都可以在这里定义;(Bean的类型,Bean。。。) RootBeanDefinition beanDefinition = new RootBeanDefinition(User03. class ); //注册一个Bean,指定bean名 registry.registerBeanDefinition( "User03" , beanDefinition); } } } |
|
1 2 3 4 5 6 7 |
public class User03 { public String username;
public User03() { System.out.println( "user03...constructor" ); } } |
使用上和前面的类似就不举例了。
法4:FactoryBean
默认获取到的是工厂bean调用getObject创建的对象。
要获取工厂Bean本身,我们需要给id前面加一个&。例如:&xxxFactoryBean 注意类名是X,这里就是小写的x
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
public class UserFactoryBean implements FactoryBean<User04> { @Override public User04 getObject() throws Exception { // TODO Auto-generated method stub System.out.println( "UserFactoryBean...getObject..." ); return new User04( "User04" ); }
@Override public Class<?> getObjectType() { // TODO Auto-generated method stub return User04. class ; }
//是否单例? //true:这个bean是单实例,在容器中保存一份 //false:多实例,每次获取都会创建一个新的bean; @Override public boolean isSingleton() { return true ; } }
public class User04 { public String username; public User04(String s) { String nowtime= DateUtil.now(); username=s+ " " +nowtime; } }
@Configuration @Import ({ImportDemo. class , MyImportSelector. class , MyImportBeanDefinitionRegistrar. class }) public class ImportConfig {
// 要获取工厂Bean本身,需要给id前面加一个&,&userFactoryBean @Bean public UserFactoryBean userFactoryBean(){ return new UserFactoryBean(); }
@Bean public User user(){ return new User( "Lily" ); } }
@RestController public class ImportDemoController { @Autowired private User user;
@Autowired private ImportDemo importDemo;
@Autowired private User01 user01;
@Autowired private UserFactoryBean userFactoryBean;
@RequestMapping ( "/importDemo" ) public String demo() throws Exception { importDemo.doSomething(); user01.username = "user01" ; String s = user.username; String s1 = user01.username; String s4 = userFactoryBean.getObject().username;
return "ImportDemo@SpringBoot " + s + " " + s1 + " " + s4; } }
@SpringBootApplication public class SpringBootLearningApplication {
public static void main(String[] args) { SpringApplication.run(SpringBootLearningApplication. class , args);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( "com.paopaoedu.springboot.config" ); ImportDemo importDemo = context.getBean(ImportDemo. class ); importDemo.doSomething(); printClassName(context);
Object bean1 = context.getBean( "userFactoryBean" ); Object bean2 = context.getBean( "userFactoryBean" ); System.out.println(bean1 == bean2); }
private static void printClassName(AnnotationConfigApplicationContext annotationConfigApplicationContext){ String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames(); for ( int i = 0 ; i < beanDefinitionNames.length; i++) { System.out.println( "匹配的类" +beanDefinitionNames[i]); } } } |
测试结果
以上就是SpringBoot向容器注册bean的方法详解的详细内容,更多关于SpringBoot注册bean的资料请关注其它相关文章!
原文链接:https://blog.csdn.net/feiying0canglang/article/details/124761970
查看更多关于SpringBoot向容器注册bean的方法详解的详细内容...