如何获取所有spring管理的bean

网友投稿 343 2022-09-27


如何获取所有spring管理的bean

目录获取所有spring管理的beanIOC容器使用ListableBeanFactory接口使用Spring Boot Actuator小结一下spring管理bean的原理使用spring时,获取spring注入的bean是这样那下面我们模拟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:

@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:

@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。

@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外,它还将打印容器中所有其他bhttp://ean。为了清晰起见,这里省略了很多。

使用Spring Boot Actuator

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

现在我们访问url: http//

:/beans,如果没有指定其他独立管理端口,我们使用缺省端口,结果会返回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

]

}

]

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

小结一下

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

spring管理bean的原理

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

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

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

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

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

代码如下:

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

2.创建spring.xml配置文件

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

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

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

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

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

主要是构造方法中的两步

// 装载实例化bean

private Map beanMap = new HashMap();

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

private List beanlist = new ArrayList();

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 nsMap = new HashMap();

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

doc = reader.read(xmlpath);

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

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

List 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, chttp://n);

beanlist.add(beans);

}

} catch (Exception e) {

http:// e.printStackTrace();

}

}

public Object getBean(String beanId) {

return beanMap.get(beanId);

}

6.实体类

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容器实例化的效果,也就是说,实际spring实例化管理bean时,也是经过两大步:

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

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:HCNA——动态路由协议基础(动态路由协议原理)
下一篇:HCNA——静态路由深入分析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~