Spring是如何管理Bean

容器是什么?spring中是如何体现的?一直有疑惑,这两天看了一下Spring管理bean的Demo,对于Spring中的容器有了简单的认识。

我们知道,容器是一个空间的概念,一般理解为可盛放物体的地方。在Spring容器通常理解为BeanFactory或者ApplicationContext。我们知道spring的IOC容器能够帮我们创建对象,对象交给spring管理之后我们就不用手动去new对象。

其中有BeanFactory与ApplicationContext两种方式可以创建对象。

那么BeanFactory与ApplicationContext的区别是什么?

BeanFactory采用了工厂设计模式,负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。而ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:国际化支持、aop、事务等。同时BeanFactory在解析配置文件时并不会初始化对象,只有在使用对象getBean()才会对该对象进行初始化,而ApplicationContext在解析配置文件时对配置文件中的所有对象都初始化了,getBean()方法只是获取对象的过程。

所以ApplicationContext的应用场景更广泛。

ApplicationContext是如何管理Bean呢?下面这个Demo简单模仿了这个原理:

1.建立一个类PersonServiceBean,并在xml文件中进行配置。

public class PersonServiceBean implements PersonService   {
    public void save(){
        System.out.println("我是save()的方法");
    }
}  
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>  

2.建立类BeanDefinition,提供一个构造函数,将其作为每个bean的公共转型类。

public class BeanDefinition {  

    private String id;
    private String className;  

    public BeanDefinition(String id, String className) {
        this.id = id;
        this.className = className;
    }
//get set方法
}
  

3.建立容器类tgbApplicationContext。

 1 /**
 2  * 测试spring容器
 3  * @author hegang
 4  *
 5  */
 6 public class tgbClassPathXMLApplicationContext {
 7
 8     private List<BeanDefinition> beanDefines =new ArrayList<BeanDefinition>();
 9     private Map<String,Object> sigletons =new HashMap<String,Object>();
10
11
12     public tgbClassPathXMLApplicationContext(String filename){
13         this.readXML(filename);
14         this.instanceBeans();
15     }
16
17     /**
18      * 完成bean的实例化
19      */
20     private void instanceBeans() {
21         for(BeanDefinition beanDefinition :  beanDefines){
22             try {
23                 if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())){
24                   sigletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance());
25                 }
26             } catch (Exception e) {
27                 // TODO Auto-generated catch block
28                 e.printStackTrace();
29             }
30
31         }
32
33     }
34
35     /**
36      * 读取xml配置文件
37      * @param filename
38      */
39     private void readXML(String filename) {
40         SAXReader saxReader = new SAXReader(); //创建读取器
41         Document document =null;
42         try{
43             URL xmlpath = this.getClass().getClassLoader().getResource(filename);
44             document =saxReader.read(xmlpath);
45             Map<String,String> nsMap =new HashMap<String,String>();
46             nsMap.put("ns","http://www.springframework.org/schema/beans"); //加入命名空间
47             XPath xsub = document.createXPath("//ns:beans/ns:bean"); //创建beans/bean查询路径
48              xsub.setNamespaceURIs(nsMap); // 设置命名空间
49             List<Element> beans = xsub.selectNodes(document); // 获取文档下所有的bean节点
50             for(Element element:beans){
51                 String id =element.attributeValue("id"); // 获取id属性值
52                 String clazz =element.attributeValue("class"); // 获取class属性值
53                 BeanDefinition beanDefine =new BeanDefinition(id,clazz);
54                 beanDefines.add(beanDefine);
55             }
56
57         } catch(Exception e){
58             e.printStackTrace();
59         }
60
61     }
62
63     /**
64      * 获取bean实例
65      * @param beanName
66      * @return
67      */
68     public Object getBean(String beanName){
69         return this.sigletons.get(beanName);
70     }
71 }  

该类中拥有一个List<BeanDefinition>泛型集合类以及一个Map<String,Object>集合。通过查看代码我们知道这个容器类所做的事情如下:

a.读取配置文件bean.xml,并根据文件中bean的id,class属性实例化一个BeanDefinition,装入泛型集合中。

b.通过循环+反射,将List<BeanDefinition>中的bean加入到Map<String,Object>中,这里用反射将bean中的className属性转换为一个实例化的bean对象加入到了Map中。

c.提供一个对外的接口,通过传入参数获取该bean。

4.下面就是通过容器类获取具体bean的代码了。

1 public class SpringTest {
2     @Test
3     public void instanceSpring(){
4         tgbClassPathXMLApplicationContext ctx =new tgbClassPathXMLApplicationContext("beans.xml");
5         PersonService personService =(PersonService) ctx.getBean("personService");
6         personService.save();
7     }
8 }  

通过这样的Demo,可以清楚看到Spring容器做的事情。它在初始化的时候将配置文件中bean以及相对应关系的配置都加入到ApplicationContext,通过一系列的转换将这些bean实例化,bean被它进行了管理,所以ApplicationContext就扮演了一个容器的角色。

原文地址:https://www.cnblogs.com/smellpawn/p/10799441.html

时间: 2024-08-29 06:45:02

Spring是如何管理Bean的相关文章

Spring(九)让Spring自动扫描和管理Bean

在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找和维护起来也不太方便.Spring2.5为我们引入了组件自动扫描机制,它可以在类路径下寻找标注了@Component.@Service.@Controller.@Repository注解的类,并把这些类纳入Spring容器中管理.它的作用和在xml文件中使用bean节点配置组件是一样的.要使用自动扫描机制,需配置以下信息: beans4.xml <?xml version="1

Spring2.5学习3.4_让Spring自动扫描和管理Bean

通过在类路径下,根据自动扫描方式,把组件纳入Spring容器管理. 如果这些组件采用xml的bean定义来进行配置,显然会增加配置文件的体积,查找以及维护起来也不太方便.Spring2.5引入了组件自动扫描机制,它可以在类路径下寻找标注了@Component,@Service,@Controrl,@Respository注解的类,并把这些类纳入Spring容器管理,它的作用和xml文件中bean节点的配置是一样的,要使用自动扫描机制,我们需要打开以下配置信息: <?xml version="

使用Spring和SpringMVC管理bean时要注意的一个小细节

最近一直在做毕业设计...用到了Shiro和SpringMVC..用过shiro的朋友都知道shiro需要自己去写Realm,然后把Realm注入到SecurityManager中.而SecurityManager是shiro自带的类..我不可能去修改源码,增加注解,所以配置这个Realm bean的时候使用的是XML的配置方式..而又因为整个项目使用到了SpringMVC,我自己写的类基本都是用注解去配置的..然后就有了这么一个问题...我的问题与配置和http://www.oschina.n

Spring中管理Bean以及解析XML

Spring是分层的轻量级框架 以IoC(Inverse of Control 反转控制)和AOP(Aspect Oriented Programming 面向切面编程)为核心 应用Spring的好处: 方便解耦,简化开发 Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理 AOP编程的支持 Spring提供面向切面编程,可以方便的实现对程序进行权限拦截.运行监控等功能 声明式事务的支持 只需要通过配置就可以完成对事务的管理,而无需手动编程 方便集成各种优秀框架

【Spring】的【Bean】管理(注解)【四个相同功能的注解】

[Spring]的[Bean]管理(注解)[四个相同功能的注解] 注解:代码里面特殊的标记,使用注解也可以完成一些相关的功能. 注解写法:@注解名称(属性名称=属性值) 注解使用在类.方法.属性上面 (注解可以替代配置文件,并非完全替代): 1.创建类,创建方法 1 public class User { 2 public void add(){ 3 System.out.println("add-----------"); 4 } 5 } 2.创建spring配置文件,引入约束 1

采用Spring管理Bean和依赖注入

1.实例化spring容器 和 从容器获取Bean目标 实例化Spring容器常用的两种办法: 办法一: 在类途径下寻觅配置文件来实例化容器 [引荐运用] ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"}); 办法二: 在文件体系途径下寻觅配置文件来实例化容器 [这种办法能够在开发期间运用] ApplicationContext ctx = new FileSyst

深入探索spring技术内幕(二): 剖析spring管理Bean的原理与配置

求二叉树的宽度和深度 给定一个二叉树,获取该二叉树的宽度和深度. 例如输入 a / \ b c / \ / \ d e f g 返回3. 详细描述: 接口说明 原型: int GetBiNodeInfo(BiNode &head, unsigned int *pulWidth, unsigned int *pulHeight) 输入参数: head 需要获取深度的二叉树头结点 输出参数(指针指向的内存区域保证有效): pulWidth 宽度 pulHeight 高度 返回值: 0 成功 1 失败

反射-Spring管理Bean,注入Bean属性的反射机制。

#反射 1.是JAVA API,是Java提供的现成的类!! --接受API提供的功能! 2. 是Java提供的动态执行机制,动态加载类,动态创建对象,动态访问属性,动态调用方法. ##反射用途 1. eclipse 中解析类的结构使用了反射 2.JUnit识别被测试方法使用了反射 -- JUnit3 利用了反射查找test开头的方法 -- JUnit4 利用了反射解析@Test查找测试方法 3.Spring 管理Bean对象,注入Bean属性使用了反射 --利用反射创建Bean对象实例 --利

如何获得Spring容器里管理的Bean,。不论是Service层,还是实体Dao层

如何获得Spring容器里管理的Bean,.不论是Service层,还是实体Dao层, 下面的这个必须配置,否则必出错,空指针 下面的这个是代码 而获得bean代码如下: serviceManagerImpl_fl=(ServiceManagerDao)MyApplicationContextUtil.getApplicationContext().getBean("serviceManagerImpl_fl");