一,配置文件
<?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-3.0.xsd"
default-lazy-init="false">
<!-- default-lazy-init="true" -->
<bean id="personDao" class="com.xiva.Person.dao.impl.PersonDaoImpl"
lazy-init="false" scope="prototype" init-method="init"
destroy-method="destory"></bean>
<bean id="beanFactory" class="com.xiva.factory.SpringBeanFactory"/>
<bean id="person" factory-bean="beanFactory"
factory-method="createInstance"/>
<bean id="moduleDao" factory-bean="beanFactory"
factory-method="createModuleDao"/>
</beans>
二,初始化ApplicationContext
ApplicationContext context =
new ClassPathXmlApplicationContext("services.xml");
以上信息都可以在spring-framework-reference.pdf中查到;该文件在目录
spring-framework-3.0.4.RELEASE\docs\spring-framework-reference\pdf
当scope="prototype",使用destroy-method是无效的。从源码中,我们可以清晰的看到。
context.close();调用了 doClose();其中的destroyBeans();是我们关心的方法。我们关心是如何销毁bean的。在这个方法中看到下面的方法。
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
可见spring的context在close时,只会帮助我们destroySingletons
三,控制反转与依赖注入
何为,控制反转;我现在的理解是:将自己的实现,交给外部容器去实现,好像有点套话。说的具体点,又怕说得有些局限性,不过还是具体的说吧,就是指,hibernate或者你的jdbc接口的实现类,交给spring来实现,而我们可以使用xml文件来配置接口的实现类。
<bean id="personDao" class="com.xiva.Person.dao.impl.PersonDaoImpl"
lazy-init="false" scope="prototype" init-method="init"
destroy-method="destory"></bean>
比如上面的配置中,我们可以从spring的context获取到personDao接口的实现类。
这样我们在service中使用personDao时,我们不需要去实现这个接口,可以从外部注入。同样是依赖于spring的注入。
当然,控制反转和依赖注入的概念也许不是这几句话能说清楚的。
四,AbstractApplicationContext实例化bean
在web,自认为spring使用servlet的过滤,读取xml文件配置,根据类反射机制来实例化bean。
AbstractApplicationContext context =
new ClassPathXmlApplicationContext("services.xml");
PersonDao personDao = (PersonDao)context.getBean("personDao");
context.close();
从上面我们可以看出,初始化时,需要给出xml文件的名称,然后,从初始的context中可以获得这个bean的实例。
下面,我们可以大约的知道,spring通过xml利用反射帮我们实例化类,而我们获取时只需要这个配置id即可。
从源码我们得知BeanDefinition这个类,就是定义我们的bean的相关属性的一个类。为了简化我们也定义一个相同功能的bean。
package com.xiva.bean;
/**
*
* @author XIVA
* @Description 用来存储bean相关信息
*/
public class MyBean {
//ID
private String beanId;
//类名
private String beanClass;
public MyBean(){
}
public MyBean(String beanId, String beanClass){
this.beanId = beanId;
this.beanClass = beanClass;
}
public String getBeanId() {
return beanId;
}
public void setBeanId(String beanId) {
this.beanId = beanId;
}
public String getBeanClass() {
return beanClass;
}
public void setBeanClass(String beanClass) {
this.beanClass = beanClass;
}
}
有了这个类后,我们就可以在读取xml时,将配置中的id和class属性放入我们上面类的实例中。至于读取xml信息,我们有很多方式,其中包括dom4J,以及DOM、SAX、JDOM。下面我分别采用了dom以及dom4j的方式来实现了读取xml。
首先定义一个抽象类。类似于AbstractApplicationContext。
package com.xiva.mySpring;
public abstract class XivaAbsAppContext {
public abstract Object getBean(String beanName);
}
dom4j的方式,在apache下载dom4j;在工程中引入dom4j.jar以及相关引用到的包。
package com.xiva.mySpring;
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;
import com.xiva.bean.MyBean;
/**
*
* @author XIVA
* @Description 简化的Spring容器
*/
public class XivaContext extends XivaAbsAppContext{
private List<MyBean> beanList = new ArrayList<MyBean>();
private Map<String, Object> sigletons = new HashMap<String, Object>();
public XivaContext(String xmlPath){
this.readXML(xmlPath);
this.instanceBean();
}
/**
* @Description 解析spring配置文件,初始化bean
* @author XIVA
* @param fileName
*/
@SuppressWarnings("unchecked")
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");//
xsub.setNamespaceURIs(nsMap);//设置命名空间
List<Element> beans = xsub.selectNodes(document);//获取节点
for(Element element:beans){
String id = element.attributeValue("id");
String clazz = element.attributeValue("class");
MyBean bean = new MyBean(id, clazz);
beanList.add(bean);
}
}catch(Exception e){
e.printStackTrace();
}
}
/**
*
* @Description 实例化bean
* @author XIVA
*/
private void instanceBean(){
Object object = null;
for(MyBean bean:beanList){
try{
String clazzStr = bean.getBeanClass();
Class<?> clazz = Class.forName(clazzStr);
object = clazz.newInstance();
sigletons.put(bean.getBeanId(), object);
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 获取Bean实例
*/
@Override
public Object getBean(String beanName) {
// TODO Auto-generated method stub
return sigletons.get(beanName);
}
}
dom的解析,这个好处就是不需要引入dom4j这个包,spring就这样做的。
package com.xiva.mySpring;
import java.io.InputStream;
import java.util.Hashtable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.xiva.bean.MyBean;
public class XivaClassXmlApplicationContext extends XivaAbsAppContext{
private static Hashtable<String,MyBean> beans = new Hashtable<String,MyBean>();
public XivaClassXmlApplicationContext(String xmlPath){
readXML(xmlPath);
}
private void readXML(String xmlPath){
InputStream is = XivaClassXmlApplicationContext.class.getClassLoader().getResourceAsStream(xmlPath);
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
try{
DocumentBuilder dombuilder = domFactory.newDocumentBuilder();
Document document = dombuilder.parse(is);
Element root = document.getDocumentElement();
NodeList nodes = root.getElementsByTagName("bean");
int length = nodes.getLength();
for(int i=0;i<length;i++){
Node childNode = nodes.item(i);
NamedNodeMap attrs = childNode.getAttributes();
MyBean bean = new MyBean();
for(int j=0;j<attrs.getLength();j++){
Node attrNode = attrs.item(j);
if("id".equals(attrNode.getNodeName())){
bean.setBeanId(attrNode.getNodeValue());
}else if("class".equals(attrNode.getNodeName())){
bean.setBeanClass(attrNode.getNodeValue());
}
}
if(bean!=null){
beans.put(bean.getBeanId(), bean);
}
}
}catch(Exception e){
System.out.println("error");
}
}
@Override
public Object getBean(String beanName){
MyBean bean = beans.get(beanName);
String className = bean.getBeanClass();
Class<?> clazz = null;
Object obj = null;
try {
clazz = Class.forName(className);
obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}
第二种,方式没有给出类似于启动spring时,就实例化所有的bean。实现方式其实通方式一。当然这里和spring差距还是很大的,但其核心原理就是上面这样。
分享到:
相关推荐
本资料“Spring学习笔记&源码”是基于网易云课堂黑马程序员的Spring四天精通课程,旨在帮助学习者深入理解和实践Spring框架。 笔记部分可能会涵盖以下内容: 1. **Spring概述**:介绍Spring框架的历史、特点和主要...
总之,Spring源码学习是一个深化编程技能,理解设计模式,以及提高问题解决能力的过程。通过深入研究,程序员不仅可以优化自己的代码,还能更高效地利用Spring框架提供的功能,提升项目的可维护性和扩展性。
马士兵老师是知名的Java教育专家,他的Spring框架学习笔记深入浅出,对于初学者和进阶者来说都是一份宝贵的资源。这份笔记涵盖了Spring的核心概念、配置、AOP(面向切面编程)、DI(依赖注入)等关键知识点。 1. **...
这份"Spring学习笔记+学习源码.zip"资源包含了深入学习Spring及其相关技术的知识点,以及实践代码,对提升Spring技能将大有裨益。 首先,我们来详细讨论Spring框架的主要组件和功能: 1. **依赖注入(Dependency ...
### Spring学习笔记(精华全记录) #### Spring框架概述 Spring框架源自Rod Johnson的个人项目,最初于2002年末发布。Spring并非一开始就作为一个完整的框架出现,而是从一个项目逐步发展而来。随着项目的成熟,...
学习Spring源码不仅可以深入理解其工作原理,还可以提升自己的编程技能和设计思维。通过阅读源码,开发者可以了解如何实现DI和AOP,以及Spring如何优雅地管理对象和处理各种框架的集成。对于初入IT行业的人员来说,...
在《Spring Boot》源码学习笔记中,我们可以深入理解其内部工作机制,包括自动配置、起步依赖、命令行接口(CLI)以及如何集成各种组件如JSP等。JSP(JavaServer Pages)是一种用于动态创建网页的技术,Spring Boot ...
本学习笔记提供了丰富的源码示例,帮助读者更好地理解和应用Spring框架。 首先,需要明确Spring是一个开源框架,它旨在简化Java EE(现在称为Jakarta EE)的开发。Spring框架的核心是提供了一个轻量级、解耦的容器...
Spring学习笔记(马士兵spring视频笔记).docSpring学习笔记(马士兵spring视频笔记).docSpring学习笔记(马士兵spring视频笔记).docSpring学习笔记(马士兵spring视频笔记).doc
这份源码学习笔记以SpringFramework 5.0.x版本为核心,详细地记录了通过debug方法学习Spring框架中的两个核心特性:控制反转(IoC)和面向切面编程(AOP)的实现原理。 首先,要学习Spring Framework 5.0.x的源码,...
本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际应用。 1. **核心概念** - **切面(Aspect)**:切面是关注点的模块化,包含业务逻辑之外的横切关注点,如日志、事务管理。 - **连接点(Join Point...
本笔记将深入探讨Spring的源码学习,重点理解其核心组件和生命周期。 首先,Spring通过反射机制来实例化对象。在Java中,我们可以使用`Class.forName()`方法根据完全限定类名获取类对象,或者通过已有对象的`...
这个"spring学习笔记,包括源码学习"的资料很可能包含了一系列关于Spring框架的核心概念、配置、使用方法以及深入源码的解析。 首先,让我们来了解一下Spring框架的基础知识。Spring的核心特性是依赖注入,它允许...
马士兵Spring课堂笔记(超级详细版) 本资源主要讲解了Spring框架的基础概念和应用,涵盖了面向接口编程、IOC/DI、AOP、Spring应用IOC/DI、Spring应用AOP、Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2整合、Spring...
Spring框架是Java开发中最常用的轻量级开源框架之一,它为构建企业级应用程序...以上是Spring5源码分析笔记中的主要知识点,深入学习这些内容将有助于开发者更好地理解和利用Spring框架,从而提高开发效率和应用质量。
Spring框架是Java开发中最常用的轻量级开源框架之一,它以IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为核心,极大地简化了企业级应用的开发工作。"Spring笔记示例源...
个人学习spring框架时记录的笔记,纯手敲,SpringIOC+SpringMVC学习笔记,有兴趣的可以参考
标题中的"Spring学习笔记之一“why spring”"表明了这篇笔记主要探讨的是Spring框架的核心价值和使用背景。在IT行业中,Spring是一个广泛使用的Java企业级应用开发框架,它以其依赖注入(Dependency Injection,DI)...
《Spring技术内幕 学习笔记》是一份深入探讨Spring框架核心机制的学习资料,结合作者zzc1684在iteye博客上的博文,我们可以从中学习到Spring框架的多个重要知识点。Spring作为Java企业级应用开发的基石,其设计思想...