您的位置:首页 > 编程语言 > Java开发

模拟Spring创建Bean和dom4j读取xml文件(视频学习-传智播客Spring2.5-03)

2011-12-29 19:26 483 查看
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
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.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

public class ItcastClassPathXMLApplicationContext {
List<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>();
Map<String, Object> beans=new HashMap<String, Object>();
public ItcastClassPathXMLApplicationContext(String path) {
// TODO Auto-generated constructor stub
this.readXML(path);
initialBeans();
injectBeans();
}
private void injectBeans() {
// TODO Auto-generated method stub
//必须在注入之前先实例化好每一个Bean
for(BeanDefinition bd:beanDefinitions){
Object bean=getBean(bd.getId());
if(bean!=null){
//注入依赖
try {
//取得Bean的属性描述
PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDefinition pd:bd.getProperties()){
//pd中的name是否存在于Bean的属性中
for(PropertyDescriptor d:pdps){
if(d.getName().equals(pd.getName())){
//取得setter方法
Method setter=d.getWriteMethod();//private方法也会出错
Object value=null;
if(setter!=null){
if(pd.getRef()!=null && !pd.getRef().equals("")){
value=getBean(pd.getRef());
}else{
value=ConvertUtils.convert(pd.getValue(), d.getPropertyType());
}
}
setter.setAccessible(true); //设置允许访问
setter.invoke(bean,value);
break;
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}
private void initialBeans() {
// TODO Auto-generated method stub
for(BeanDefinition b:beanDefinitions){
if(b.getClassName()!=null&& !b.getClass().equals(""))
try {
beans.put(b.getId(), Class.forName(b.getClassName()).newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 读取xml配置文件
* @param path
*/
private void readXML(String path) {
// TODO Auto-generated method stub
SAXReader reader=new SAXReader();//创建读取器
URL url=getClass().getClassLoader().getResource(path);
Document doc=null;
try {
doc=reader.read(url);
//存放命名空间
Map<String,String> nsps=new HashMap<String,String>();
nsps.put("ns", "http://www.springframework.org/schema/beans");
XPath ePath=doc.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
ePath.setNamespaceURIs(nsps);
List<Element> eList=ePath.selectNodes(doc);//获取文档下所有bean节点
for(Element e:eList){
String id=e.attributeValue("id");
String className=e.attributeValue("class");

BeanDefinition bDefinition=new BeanDefinition(id, className);
//读取property
XPath pXPath=e.createXPath("ns:property");//当前元素
pXPath.setNamespaceURIs(nsps);
List<Element> pros=pXPath.selectNodes(e);
for(Element e2:pros){
String name=e2.attributeValue("name");
String ref=e2.attributeValue("ref");
String value=e2.attributeValue("value");

//System.out.println(name+" "+ref);
PropertyDefinition pd=new PropertyDefinition(name, ref,value);
bDefinition.getProperties().add(pd);
}
beanDefinitions.add(bDefinition);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object getBean(String id){
return beans.get(id);
}
}



加入注解解析功能:

定义注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//表示使用的范围,编译器、运行期
@Retention(RetentionPolicy.RUNTIME)
//注解可以加入的位置
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface ItcastResource {
String name() default "";
}


注解解析器做的事情。该方法加入到上面ItcastClassPathXMLApplicationContext中的构造函数中。

private void annotationInject() {
// TODO Auto-generated method stub
for(BeanDefinition bd:beanDefinitions){
Object bean=getBean(bd.getId());
if(bean!=null){
try {
//取得所有的属性
PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDescriptor pdesc:pdps){
//判断setter上是否存在注解
Method setter=pdesc.getWriteMethod();
if(setter!=null&& setter.isAnnotationPresent(ItcastResource.class)){
//取出注解的name属性
ItcastResource itRes=setter.getAnnotation(ItcastResource.class);
Object value=null;
if(itRes.name()!=null&&!itRes.name().equals("")){
value=getBean(itRes.name());
}else{
//取得属性的名称
value=getBean(pdesc.getName());
if(value==null){//按类型找
//遍历所有的bean
for(String key:beans.keySet()){
//类型匹配
if(pdesc.getPropertyType().isAssignableFrom(beans.get(key).getClass())){
value=beans.get(key);
break;
}

}
}
}
setter.setAccessible(true);
setter.invoke(bean, value);
}
}
//取得字段
Field[] fields=bean.getClass().getDeclaredFields();
for(Field f:fields){
//是否存在注解
if(f.isAnnotationPresent(ItcastResource.class)){
ItcastResource itRes=f.getAnnotation(ItcastResource.class);
Object value=null;
if(itRes.name()!=null&&!itRes.name().equals("")){
value=getBean(itRes.name());
}else{
//取得属性的名称
value=getBean(f.getName());
if(value==null){//按类型找
//遍历所有的bean
for(String key:beans.keySet()){
//类型匹配
if(f.getType().isAssignableFrom(beans.get(key).getClass())){
value=beans.get(key);
break;
}

}
}
}
f.setAccessible(true);
f.set(bean, value);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: