1、定义一个接口
package com.css.framework.context;
public interface MyApplicationContext {
/**
* 获取bean的实例
* @param beanName
* @return
*/
public Object getBean(String beanName);
}
2、Bean节点的描述文件
package com.css.framework.beans.factory.config;
import java.util.ArrayList;
import java.util.List;
/**
* Spring Bean 的描述文件
*
* @author Administrator
*
*/
public class BeanDefinition {
//Bean节点中的id属性
private String id;
//Bean节点中的className属性
private String className;
/**
* Bean节点中的属性描述property节点
*/
private List<PropertyDefinition> properties = new ArrayList<PropertyDefinition>();
public String getId() {
return id;
}
public BeanDefinition(String id, String className) {
super();
this.id = id;
this.className = className;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<PropertyDefinition> getProperties() {
return properties;
}
public void setProperties(List<PropertyDefinition> properties) {
this.properties = properties;
}
}
package com.css.framework.beans.factory.config;
/**
*
* <p>Title: property节点的描述文件 </p>
* <p>Description: property节点的描述文件</p>
* <p>Copyright: Copyright (c) 2010,CSS</p>
* <p>Company: CSS</p>
* @author 章殷
* @date 2010-6-19
* @version 1.0
*/
public class PropertyDefinition {
private String name;
private String ref;
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public PropertyDefinition(String name, String ref,String value) {
super();
this.name = name;
this.ref = ref;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}
4、关键的实现类
package com.css.framework.context;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.ConvertUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import com.css.framework.annotation.MyResource;
import com.css.framework.beans.factory.config.BeanDefinition;
import com.css.framework.beans.factory.config.PropertyDefinition;
import com.css.inter.IConstructorServiceBean;
/**
*
* <p>Title: 加载beans.xml文件 </p>
* <p>Description: 加载xml文件,实例化文件中的Bean,并实现IOC</p>
* <p>Copyright: Copyright (c) 2010,CSS</p>
* <p>Company: CSS</p>
* @author 章殷
* @date 2010-6-19
* @version 1.0
*/
public class MyClassPathXmlApplicationContext implements MyApplicationContext {
//所有的bean的描述文件列表
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
//定义所有的实例化的Bean
private Map<String, Object> sigletons = new HashMap<String, Object>();
public MyClassPathXmlApplicationContext(String filename) {
//加载配置文件
readXml(filename);
//实例化配置文件中的Bean
instanceBeans();
//使用注解方法进行注入
annotationInject();
//给Bean注入对象
injectObject();
}
/**
* <p> 使用注解的方式,将对象注入到实例Bean中。</p>
* @author 章 殷
* @date 2010-6-19
*/
private void annotationInject() {
//循环所有实例化的Bean
for (String beanName : sigletons.keySet()) {
//获取Bean
Object bean = sigletons.get(beanName);
if (bean != null) {
try {
//通过属性注入
propertyInject(bean);
//通过字段注入,包括字段的名称
fieldInject(bean);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* <p> 通过属性名属性类型进行注入。</p>
* @param bean
* @throws IntrospectionException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @author 章 殷
* @date 2010-6-19
*/
private void propertyInject(Object bean) throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
//获取Bean的属性描述信息,通过setter方法进行注入
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDesc : ps) {
//获取属性的setter方法
Method setter = propertyDesc.getWriteMethod();
//判断setter方法是否存储,时候存在MyResource注解
if (setter != null && setter.isAnnotationPresent(MyResource.class)) {
//获取属性的注解
MyResource resource = setter.getAnnotation(MyResource.class);
Object value = null;
//判断注解的name值是否为空,是否为空字符
if (resource.name() != null && !"".equals(resource.name())) {
//从容器中取出name对应的对象
value = sigletons.get(resource.name());
}
//下面的方法是通过属性名和属性的类型来查找实例Bean
else {
//通过属性名来查找对应的实体Bean
value = sigletons.get(propertyDesc.getName());
if (value == null) {
//通过属性的类型来查找对应的实体Bean
for (String key : sigletons.keySet()) {
// 循环所有的容器Bean,判断属性的类型和容器中的类型是否匹配
if (propertyDesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())) {
value = sigletons.get(key);
break;
}
}
}
}
setter.setAccessible(true);//如果是私有的方法,设置该值为true,就可以调用该setter方法
setter.invoke(bean, value); //把引用注入到Bean中
}
}
}
/**
* <p> 通过字段名进行实例注入。</p>
* @param bean
* @throws IllegalAccessException
* @author 章 殷
* @date 2010-6-19
*/
private void fieldInject(Object bean) throws IllegalAccessException {
//获取Bean的所有字段信息
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
//判断字段上是否存在MyResource注解
if (field.isAnnotationPresent(MyResource.class)) {
MyResource resource = field.getAnnotation(MyResource.class);
Object value = null;
//通过注解的Name属性来查询实体Bean
if (resource.name() != null && !"".equals(resource.name())) {
value = sigletons.get(resource.name());
}
//通过字段的名称和字段类型来查询实例Bean
else {
value = sigletons.get(field.getName());//通过属性名来查找
if (value == null) {
for (String key : sigletons.keySet()) {
if (field.getType().isAssignableFrom(sigletons.get(key).getClass())) {
value = sigletons.get(key);
break;
}
}
}
}
field.setAccessible(true);//设置私有的属性可以进行访问
field.set(bean, value); //将应用注入到属性中
}
}
}
/**
* <p> IOC的Spring的实现,该方法是用的是属性注入,可以注入依赖对象和基本数据类型。</p>
* @author 章 殷
* @date 2010-6-18
*/
private void injectObject() {
System.out.println("============开始进行IOC注入==============");
//循环所有的beanDefines
for (BeanDefinition beanDefinition : beanDefines) {
//获取实例化后的bean
Object bean = sigletons.get(beanDefinition.getId());
if (bean != null) {
//获取实例化后的Bean的属性描述西西里
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for (PropertyDefinition propertyDefinition : beanDefinition.getProperties()) {
for (PropertyDescriptor propertyDescriptor : ps) {
Method setter = null;
//判断Bean的属性名 与 property节点中的Name值是否相同
if (propertyDefinition.getName().equals(propertyDescriptor.getName())) {
setter = propertyDescriptor.getWriteMethod();//获取实例化Bean的set方法
if (setter != null) {
Object value = null;
//如果引用存在,注入依赖对象
if (propertyDefinition.getRef() != null
&& !"".equals(propertyDefinition.getRef().trim())) {
value = sigletons.get(propertyDefinition.getRef());//从容器中获取ref的Bean
}
//注入基本数据类型
else {
value = ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor
.getPropertyType());
}
setter.setAccessible(true);//如果是私有的方法,设置该值为true,就可以调用该setter方法
setter.invoke(bean, value); //把引用注入到Bean中
System.out.println("注入[" + beanDefinition.getClassName() + "]的"
+ propertyDefinition.getName() + "属性成功");
}
}
}
}
} catch (Exception e) {
System.err.println("注入【" + beanDefinition.getClassName() + "】时出错!");
}
}
}
System.out.println("============IOC注入完成==============");
System.out.println("");
}
/**
* <p> 实例化beanDefines中的所有Bean。</p>
* @author 章 殷
* @date 2010-6-18
*/
private void instanceBeans() {
System.out.println("============开始实例化Bean==============");
for (BeanDefinition beanDefinition : beanDefines) {
try {
if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) {
sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
System.out.println("实例化[" + beanDefinition.getClassName() + "]成功!");
}
} catch (Exception e) {
System.err.println("实例化[" + beanDefinition.getClassName() + "]时出错!");
e.printStackTrace();
}
}
System.out.println("============实例化Bean完成==============");
System.out.println("");
}
/**
* <p> 读取bean.xml文件,将xml的描述文件转换为java描述文件。</p>
* @param filename
* @author 章 殷
* @date 2010-6-18
*/
@SuppressWarnings("unchecked")
private void readXml(String filename) {
System.out.println("============开始加载配置文件" + filename + "==============");
SAXReader saxReader = new SAXReader();
Document document = null;
URL xmlpath = this.getClass().getClassLoader().getResource(filename);
try {
document = saxReader.read(xmlpath);
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");
//定位到beans/bean节点下
XPath xsub = document.createXPath("//ns:beans//ns:bean");
xsub.setNamespaceURIs(nsMap); //设置命名空间
List<Element> beans = xsub.selectNodes(document); //获取xml中所有的bean节点
for (Element element : beans) {
String id = element.attributeValue("id"); //获取属性id的值
String clazz = element.attributeValue("class");//获取属性class的值
BeanDefinition beanDefinition = new BeanDefinition(id, clazz);
//将Bean.xml文件中的property节点映射到beanDefinition
XPath propertySub = element.createXPath("ns:property"); //创建property的相对路径
propertySub.setNamespaceURIs(nsMap);
List<Element> propertis = propertySub.selectNodes(element);
for (Element property : propertis) {
String propertyName = property.attributeValue("name");
String propertyRef = property.attributeValue("ref");
String propertyValue = property.attributeValue("value");
beanDefinition.getProperties().add(
(new PropertyDefinition(propertyName, propertyRef, propertyValue)));
System.out.println(">>>>:加载属性[" + clazz + ".(" + propertyRef + ")]成功!");
}
beanDefines.add(beanDefinition);
System.out.println(">>>>:加载类[" + clazz + "]成功!");
}
} catch (DocumentException e) {
System.err.println("加载配置文件<" + xmlpath + ">时出错!");
e.printStackTrace();
}
System.out.println("============配置文件" + filename + "加载完成==============");
System.out.println("");
}
/**
* 获取bean的实例
* @param beanName
* @return
*/
public Object getBean(String beanName) {
return sigletons.get(beanName);
}
public static void main(String[] args) {
MyApplicationContext context = new MyClassPathXmlApplicationContext("beans.xml");
// IPersonServiceBean personService = (IPersonServiceBean) context.getBean("personService");
// personService.save();
IConstructorServiceBean constructor = (IConstructorServiceBean) context.getBean("constructorServiceBean");
constructor.save();
}
}
分享到:
相关推荐
而自动扫描和自动注入是Spring 2.5中实现IOC的两个核心特性,极大地简化了配置工作,提高了开发效率。以下是对这两个特性的详细解释: **自动扫描**: 自动扫描是Spring框架的一个强大功能,它允许开发者指定一个或...
《精通Spring2.5》是一本深度探讨Spring框架的权威指南,主要针对Spring 2.5版本进行深入解析。Spring是Java企业级应用开发中最受欢迎的框架之一,它以其轻量级、模块化的设计,以及对IoC(Inversion of Control,...
Spring2.5版本是该框架的一个重要里程碑,它在2008年发布,带来了许多新特性和改进,提升了开发者在构建应用程序时的灵活性和效率。 **依赖注入(DI)和控制反转(IoC)** Spring的核心特性之一是依赖注入(Dependency...
这个"Spring2.5-中文参考手册chm.zip"文件包含了关于Spring 2.5版本的详细中文指南,对于学习和理解Spring框架具有很高的价值。 Spring框架的核心特性包括依赖注入(Dependency Injection,DI)、面向切面编程...
1. **IoC容器**:在Spring 2.5中,Bean工厂是IoC容器的核心,它负责管理对象的生命周期和依赖关系。开发者可以通过XML配置文件或注解来定义Bean及其依赖,实现组件的解耦。Spring 2.5增强了对注解的支持,使得无需...
Spring2.5是全面的企业级应用框架,它不仅包含IoC(Inversion of Control,控制反转)容器,用于管理对象的生命周期和依赖关系,还提供了AOP(Aspect-Oriented Programming,面向切面编程)功能,实现了对横切关注点...
以上就是 Spring 2.5 中的一些核心知识点,这个压缩包中的“spring常用包”可能包含了实现这些功能的相关类库和配置文件。学习和掌握这些内容,将有助于你更好地利用 Spring 2.5 构建高效、可维护的 Java 应用程序。
Spring2.5和Hibernate3集成 采用声明式事务 1.声明式事务的配置 * 配置sessionFactory * 配置事务管理器 * 配置事务的传播特性 * 配置哪些类哪些方法使用事务 2.编写业务逻辑方法 * 继承...
使用 Spring 2.5 的 Autowired 实现注释型的 IOC 在 Spring 2.5 中,Autowired 是一个非常重要的特性,它可以实现快速的自动注入,无需在 XML 文档里面添加 bean 的声明,大大减少了 XML 文档的维护。下面我们将...
标题中的"spring2.5相关的jar包"指的是Spring框架2.5版本的相关依赖库。在Spring 2.5版本中,引入了一些重要的改进和新特性,对于理解这个版本的jar包内容至关重要。 首先,Spring 2.5引入了对JSR-303(JavaBeans ...
Spring2.5-Reference_zh_CN.chm Spring2.5-中文参考手册.chm spring——AOP,IOC.doc Spring框架快速入门之简介.doc spring配置全书.doc Spring中的IOC与AOP详解.ppt
例如,你可以深入探究IoC(Inversion of Control)容器是如何管理bean的生命周期,以及AOP(Aspect-Oriented Programming)如何实现切面编程。此外,还可以研究Spring MVC的处理流程,了解请求是如何被路由到相应的...
在Spring2.5中,IoC容器支持通过XML配置文件或注解的方式定义和管理Bean之间的依赖关系。 #### 三、Bean定义与管理 - **Bean定义**:Spring框架中的Bean是应用程序的基本组成部分,它们通常代表业务实体或服务组件...
Spring框架的基础是依赖注入(DI)原理,通过控制反转(IoC)来实现对象间的依赖关系,从而降低代码的耦合性。Spring 2.5是Spring框架的一个重要版本,它在2007年发布,并引入了众多新特性,极大地促进了Java开发的...
【标题】"cxf+Spring2.5" 指的是使用Apache CXF框架与Spring 2.5版本进行集成的示例项目。Apache CXF是一个开源服务框架,它允许开发人员创建和消费Web服务,而Spring框架则是一个广泛使用的Java企业级应用的IOC...
本实例是针对Spring 2.5与Hibernate集成的实战演示,旨在展示如何利用Spring的依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IoC)容器来管理Bean,并通过Spring的面向切面编程...
AOP则是Spring提供的另一种编程范式,用于实现如日志记录、性能监控等横切关注点。此外,手册还涵盖了Spring与JDBC、Hibernate、MyBatis等持久层框架的集成,以及Spring MVC的使用。 2. **Spring 2.5 PPT**: 这个...
【Spring 2.5 教程(传智)】是一个针对初学者的全面Spring框架教程,旨在帮助开发者理解和掌握Spring的核心特性和使用方法。以下是该教程涵盖的主要知识点: 1. **Spring 概述**:Spring是一个开源的Java平台,它...