好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SpringBoot向容器注册bean的方法详解

简介

本文用示例介绍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的方法详解的详细内容...

  阅读:32次