Spring-管理bean原理

本文介绍了Spring管理bean的原理,通过一个简单的例子展示了如何使用Spring容器创建bean并进行管理。首先,Spring降低了组件间的耦合度,提供事务管理、AOP支持等服务。接着,以PersonService为例,解释了BeanDefinition类用于存储bean信息,通过读取XML配置文件,利用DOM4J解析并实例化bean。最后,模拟了一个简单的Spring容器ItcastClassPathXMLApplicationContext,演示了bean的实例化过程和从容器中获取bean实例的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、为什么使用spring

在项目中引入spring立即可以带来下面的好处:
1、降低组件之间的偶合度,实现软件各层之间的解偶。
2、可以使用容器提供众多的服务,如:事务管理服务、消息服务等。
3、容器提供单例模式支持,开发人员不需要自己编写实现代码。
4、容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。
5、容器提供了众多辅助类,使用这些类能够加快应用的开发,如:JdbcTemplateHibernateTemplate
6Spring对于主流的应用框架提供了集成支持,如集成HibernateJPAStruts等。

二、Spring管理bean原理

PersonService.java 
Java代码 
package cn.itcast.service;   
public interface PersonService {   
    public void save();   
}   

PersonServiceBean.java
package cn.itcast.service.impl;   
import cn.itcast.service.PersonService;   
public class PersonServiceBean implements PersonService {   
    public void save(){   
        System.out.println("
传智播客版容器:  我是save()方法");   
    }   

BeanDefinition.java 
Java代码 
package junit.test;   
/*  
 *
在读取配置文件的时候,我们会把读取到bean的信息存放在这个javabean对象里面去  
 * */  
public class BeanDefinition {   
    private String id;   
    private String className;   
    public BeanDefinition(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;   
    }   

beans.xml 
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">  
          <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>  
</beans> 

前面我们学习了怎样把bean交给Spring容器管理,怎样从Spring容器获取bean实例,相信大家肯定会有很多疑问,其中一个疑问是:  Spring容器内部怎么帮我们创建,管理bean的? 
  接下来解说一下,到底Spring容器内部是如何创建bean的。 我们模拟Spring容器,来建一个传智播客版的Spring容器 
ItcastClassPathXMLApplicationContext.java 
Java
代码 
package junit.test;   
  
import java.net.URL;   
import java.util.ArrayList;   
import java.util.HashMap;   
import java.util.List;   
import java.util.Map;   
  
import org.dom4j.Document;   
import org.dom4j.Element;   
import org.dom4j.XPath;   
import org.dom4j.io.SAXReader;   
  
/**  
 *
传智播客版的Spring容器  
 */  
public class ItcastClassPathXMLApplicationContext {   
    private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();   
    private Map<String, Object> sigletons = new HashMap<String, Object>();   
  
    //
存放bean实例   
  
    public ItcastClassPathXMLApplicationContext(String filename) {   
        //
模拟内部的实现,首先要读取配置文件,可以用dom4j   
        this.readXML(filename);   
        //
读取完bean之后,Spring要对bean进行实例化,怎么实现实例化呢? 通过反射机制就很容易做到   
        this.instanceBeans();   
    }   
  
    /**  
     *
实现bean的实例化  
     */  
    private void instanceBeans() {   
        for (BeanDefinition beanDefinition : beanDefines) {   
            try {   
                if (beanDefinition.getClassName() != null  
                        && !"".equals(beanDefinition.getClassName().trim()))   
                    sigletons.put(beanDefinition.getId(), Class.forName(   
                            beanDefinition.getClassName()).newInstance());   
                //
通过反射技术把bean都创建出来   
            } catch (Exception e) {   
                e.printStackTrace();   
            }   
        }   
  
    }   
  
    /**  
     *
读取xml配置文件  
     *   
     * @param filename  
     */  
    private void readXML(String filename) {   
        SAXReader saxReader = new SAXReader();   
        Document document = null;   
        try {   
            URL xmlpath = this.getClass().getClassLoader()   
                    .getResource(filename);   
            document = saxReader.read(xmlpath);   
            Map<String, String> nsMap = new HashMap<String, String>();   
            nsMap.put("ns", "
http://www.springframework.org/schema/beans");// 加入命名空间   
            XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径   
            xsub.setNamespaceURIs(nsMap);// 设置命名空间   
            List<Element> beans = xsub.selectNodes(document);// 获取文档下所有bean节点   
            for (Element element : beans) {   
                String id = element.attributeValue("id");//
获取id属性值   
                String clazz = element.attributeValue("class"); // 获取class属性值   
                BeanDefinition beanDefine = new BeanDefinition(id, clazz);   
                beanDefines.add(beanDefine);   
            }   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
    }   
  
    /**  
     *
获取bean实例  
     *   
     * @param beanName  
     * @return  
     */  
    public Object getBean(String beanName) {   
        return this.sigletons.get(beanName);   
    }   

之后做下测试:看从传智播客版的容器里是否能够取到bean实例? 
SpringTest.java 
Java
代码 
package junit.test;   
  
  
import org.junit.BeforeClass;   
import org.junit.Test;   
  
import cn.itcast.service.PersonService;   
  
public class SpringTest {   
  
    @BeforeClass  
    public static void setUpBeforeClass() throws Exception {   
    }   
  
    @Test public void instanceSpring(){   
        ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml");   
        PersonService personService = (PersonService)ctx.getBean("personService");   
        personService.save();   
    }   

package junit.test;


import org.junit.BeforeClass;
import org.junit.Test;

import cn.itcast.service.PersonService;

public class SpringTest {

 @BeforeClass
 public static void setUpBeforeClass() throws Exception {
 }

 @Test public void instanceSpring(){
  ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml");
  PersonService personService = (PersonService)ctx.getBean("personService");
  personService.save();
 }
}

运行单元测试,打印结果是  
传智播客版容器:  我是save()方法 
这句话是业务方法打印出来的。 
在控制台里,我们通过传智播客版的Spring容器取到了bean实例,并且成功的调用了它的save方法。 这里大家就可以了解,到底Spring内部是如何创建和管理bean的,当然这只是个模拟的代码,实际中可能要处理的情况还是很复杂,这例子是为了便于大家理解

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值