好得很程序员自学网

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

如何获取所有spring管理的bean

获取所有spring管理的bean

本文我们探索使用不同的方式获取spring容器中所有bean。

IOC容器

bean是基于spring应用的基础,所有bean都驻留在ioc容器中,由容器负责管理bean生命周期

有两种方式可以获取容器中的bean:

- 使用ListableBeanFactory接口

- 使用Spring Boot Actuator

使用ListableBeanFactory接口

ListableBeanFactory接口提供了getBeanDefinitionNames() 方法,能够返回所有定义bean的名称。该接口被所有factory实现,负责预加载bean定义去枚举所有bean实例。官方文档提供所有其子接口及其实现。

下面示例使用Spring Boot 构建:

首先,我们创建一些spring bean,先定义简单的Controller FooController:

?

1

2

3

4

5

6

7

8

9

10

11

@Controller

public class FooController {

     @Autowired

     private FooService fooService;

     @RequestMapping (value= "/displayallbeans" )

     public String getHeaderAndBody(Map model){

         model.put( "header" , fooService.getHeader());

         model.put( "message" , fooService.getBody());

         return "displayallbeans" ;

     }

}

该Controller依赖另一个spring Bean FooService:

?

1

2

3

4

5

6

7

8

9

10

11

@Service

public class FooService {

     public String getHeader() {

         return "Display All Beans" ;

     }

     public String getBody() {

         return "This is a sample application that displays all beans "

           + "in Spring IoC container using ListableBeanFactory interface "

           + "and Spring Boot Actuators." ;

     }

}

我们创建了两个不同的bean:

1. fooController

2. fooService

现在我们运行该应用。使用applicationContext 对象调用其 getBeanDefinitionNames() 方法,负责返回applicationContext上下文中所有bean。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@SpringBootApplication

public class Application {

     private static ApplicationContext applicationContext;

     public static void main(String[] args) {

         applicationContext = SpringApplication.run(Application. class , args);

         displayAllBeans();

     }

     public static void displayAllBeans() {

         String[] allBeanNames = applicationContext.getBeanDefinitionNames();

         for (String beanName : allBeanNames) {

             System.out.println(beanName);

         }

     }

}

会输出applicationContext上下文中所有bean:

fooController

fooService

//other beans

需注意除了我们定义的bean外,它还将打印容器中所有其他bean。为了清晰起见,这里省略了很多。

使用Spring Boot Actuator

Spring Boot Actuator提供了用于监视应用程序统计信息的端点(endpoint)。除了/beans,还包括很多其他端点,官方文档有详细说明。

现在我们访问url: http//

:/beans,如果没有指定其他独立管理端口,我们使用缺省端口,结果会返回json,包括容器所有定义的bean信息:

?

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

[

     {

         "context" : "application:8080" ,

         "parent" : null ,

         "beans" : [

             {

                 "bean" : "fooController" ,

                 "aliases" : [],

                 "scope" : "singleton" ,

                 "type" : "com.baeldung.displayallbeans.controller.FooController" ,

                 "resource" : "file [E:/Workspace/tutorials-master/spring-boot/target

                   /classes/com/baeldung/displayallbeans/controller/FooController. class ]",

                 "dependencies" : [

                     "fooService"

                 ]

             },

             {

                 "bean" : "fooService" ,

                 "aliases" : [],

                 "scope" : "singleton" ,

                 "type" : "com.baeldung.displayallbeans.service.FooService" ,

                 "resource" : "file [E:/Workspace/tutorials-master/spring-boot/target/

                   classes/com/baeldung/displayallbeans/service/FooService. class ]",

                 "dependencies" : []

             },

             // ...other beans

         ]

     }

]

当然,结果同样包括很多其他的bean,为了简单起见,这里没有列出。

小结一下

上面介绍了使用ListableBeanFactory 接口和 Spring Boot Actuators 返回spring 容器中所有定义的bean信息。

spring管理bean的原理

Spring容器默认情况下,当服务启动时,解析配置文件,实例化文件中的所有类。

使用spring时,获取spring注入的bean是这样

?

1

2

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");

               MyService myService1 = (MyService) ctx.getBean("myService");

那下面我们模拟spring管理bean这个的过程

代码如下:

1.第一步,创建java project,引入spring.jar

2.创建spring.xml配置文件

?

1

2

3

4

<? xml version = "1.0" encoding = "UTF-8" ?>

< beans xmlns = "http://HdhCmsTestspringframework.org/schema/beans" xmlns:xsi = "http://HdhCmsTestw3.org/2001/XMLSchema-instance"

        xsi:schemaLocation = "http://HdhCmsTestspringframework.org/schema/beans http://HdhCmsTestspringframework.org/schema/beans/spring-beans-2.5.xsd" >

  </ beans >

3.创建接口MyService,只需要一个测试方法save

4.创建实现类MyServiceImpl,控制台输出一句话

5.创建一个自己的解析类MyClassPathXmlApplicationContext

主要是构造方法中的两步

?

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

// 装载实例化bean

        private Map<String, Object> beanMap = new HashMap<String, Object>();

        // 装载配置文件的属性和值

        private List<MyBeans> beanlist = new ArrayList<MyBeans>();     

        public MyClassPathXmlApplicationContext(String filename) {

               //第一步,解析spring配置文件

               readXml(filename);

               //第二步,通过反射,实例化所有注入bean

               initBeans();

        }

 

        /**

         * 通过反射机制,初始化配置文件中的bean

         */

        private void initBeans() {

               for (MyBeans bean : beanlist) {

                      try {

                             if (bean.getClassName() != null && ! "" .equals(bean.getClassName())) {

                                    beanMap.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());

                             }

                      } catch (Exception e) {

                             e.printStackTrace();

                      }

               }

        }

 

        /**

         * 解析配置文件,把解析后的bean设置到实体中,并保持到list

         *

         * @param filename

         */

        private void readXml(String filename) {

               SAXReader reader = new SAXReader();

 

               Document doc = null ;

               URL xmlpath = this .getClass().getClassLoader().getResource(filename);

               try {

                      Map<String, String> nsMap = new HashMap<String, String>();

                      nsMap.put( "ns" , "http://HdhCmsTestspringframework.org/schema/beans" );

                      doc = reader.read(xmlpath);

                      XPath xpath = doc.createXPath( "//ns:beans//ns:bean" );// 创建//ns:beans//ns:bean查询路径

                      xpath.setNamespaceURIs(nsMap); // 设置命名空间

                      List<Element> eles = xpath.selectNodes(doc); // 取得文档下所有节点

                      for (Element element : eles) {

                             String id = element.attributeValue( "id" );

                             String cn = element.attributeValue( "class" );

                             //自定义实体bean,保存配置文件中id和class

                             MyBeans beans = new MyBeans(id, cn);

                             beanlist.add(beans);

                      }

               } catch (Exception e) {

                      e.printStackTrace();

               }

 

        }

 

        public Object getBean(String beanId) {

               return beanMap.get(beanId);

        }

6.实体类

?

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

package com.mooing.service;

public class MyBeans {

        private String id;

        private String className;

        public MyBeans(String id, String className) {

               this .id = id;

               this .className = className;

        }

 

        public String getId() {

               return id;

        }

 

        public void setId(String id) {

               this .id = id;

        }

 

        public String getClassName() {

               return className;

        }

 

        public void setClassName(String className) {

               this .className = className;

        }

}

7.测试

?

1

2

3

MyClassPathXmlApplicationContext ctx = new MyClassPathXmlApplicationContext( "spring.xml" );

   MyService myService = (MyService) ctx.getBean( "myService" );

   myService.save();

小结一下

自定义代码同样可以得到使用spring容器实例化的效果,也就是说,实际spring实例化管理bean时,也是经过两大步:

第一:服务启动解析配置文件,并保存配置文件中的元素;

第二:实例化所有元素,并提供获取实例方法。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/neweastsun/article/details/80464893

查看更多关于如何获取所有spring管理的bean的详细内容...

  阅读:37次