溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么獲取所有spring管理的bean

發(fā)布時(shí)間:2021-09-15 14:59:57 來源:億速云 閱讀:154 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下怎么獲取所有spring管理的bean,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

IOC容器

bean是基于spring應(yīng)用的基礎(chǔ),所有bean都駐留在ioc容器中,由容器負(fù)責(zé)管理bean生命周期

有兩種方式可以獲取容器中的bean:

- 使用ListableBeanFactory接口

- 使用Spring Boot Actuator

使用ListableBeanFactory接口

ListableBeanFactory接口提供了getBeanDefinitionNames() 方法,能夠返回所有定義bean的名稱。該接口被所有factory實(shí)現(xiàn),負(fù)責(zé)預(yù)加載bean定義去枚舉所有bean實(shí)例。官方文檔提供所有其子接口及其實(shí)現(xiàn)。

下面示例使用Spring Boot 構(gòu)建:

首先,我們創(chuàng)建一些spring bean,先定義簡單的Controller FooController:

@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依賴另一個(gè)spring Bean FooService:

@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.";
    }
}

我們創(chuàng)建了兩個(gè)不同的bean:

1.fooController

2.fooService

現(xiàn)在我們運(yùn)行該應(yīng)用。使用applicationContext 對(duì)象調(diào)用其 getBeanDefinitionNames() 方法,負(fù)責(zé)返回applicationContext上下文中所有bean。

@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);
        }
    }
}

會(huì)輸出applicationContext上下文中所有bean:

fooController

fooService

//other beans

需注意除了我們定義的bean外,它還將打印容器中所有其他bean。為了清晰起見,這里省略了很多。

使用Spring Boot Actuator

Spring Boot Actuator提供了用于監(jiān)視應(yīng)用程序統(tǒng)計(jì)信息的端點(diǎn)(endpoint)。除了/beans,還包括很多其他端點(diǎn),官方文檔有詳細(xì)說明。

現(xiàn)在我們?cè)L問url: http//

:/beans,如果沒有指定其他獨(dú)立管理端口,我們使用缺省端口,結(jié)果會(huì)返回json,包括容器所有定義的bean信息:

[
    {
        "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
        ]
    }
]

當(dāng)然,結(jié)果同樣包括很多其他的bean,為了簡單起見,這里沒有列出。

小結(jié)一下

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

spring管理bean的原理

Spring容器默認(rèn)情況下,當(dāng)服務(wù)啟動(dòng)時(shí),解析配置文件,實(shí)例化文件中的所有類。

使用spring時(shí),獲取spring注入的bean是這樣

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
              MyService myService1 = (MyService) ctx.getBean("myService");

那下面我們模擬spring管理bean這個(gè)的過程

代碼如下:

1.第一步,創(chuàng)建java project,引入spring.jar

2.創(chuàng)建spring.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 </beans>

3.創(chuàng)建接口MyService,只需要一個(gè)測試方法save

4.創(chuàng)建實(shí)現(xiàn)類MyServiceImpl,控制臺(tái)輸出一句話

5.創(chuàng)建一個(gè)自己的解析類MyClassPathXmlApplicationContext

主要是構(gòu)造方法中的兩步

// 裝載實(shí)例化bean
       private Map<String, Object> beanMap = new HashMap<String, Object>();
       // 裝載配置文件的屬性和值
       private List<MyBeans> beanlist = new ArrayList<MyBeans>();      
       public MyClassPathXmlApplicationContext(String filename) {
              //第一步,解析spring配置文件
              readXml(filename);
              //第二步,通過反射,實(shí)例化所有注入bean
              initBeans();
       }
 
       /**
        * 通過反射機(jī)制,初始化配置文件中的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設(shè)置到實(shí)體中,并保持到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://www.springframework.org/schema/beans");
                     doc = reader.read(xmlpath);
                     XPath xpath = doc.createXPath("//ns:beans//ns:bean");// 創(chuàng)建//ns:beans//ns:bean查詢路徑
                     xpath.setNamespaceURIs(nsMap);// 設(shè)置命名空間
                     List<Element> eles = xpath.selectNodes(doc);// 取得文檔下所有節(jié)點(diǎn)
                     for (Element element : eles) {
                            String id = element.attributeValue("id");
                            String cn = element.attributeValue("class");
                            //自定義實(shí)體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.實(shí)體類

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.測試

MyClassPathXmlApplicationContext ctx = new MyClassPathXmlApplicationContext("spring.xml");
  MyService myService = (MyService) ctx.getBean("myService");
  myService.save();

以上是“怎么獲取所有spring管理的bean”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI