zoukankan      html  css  js  c++  java
  • 模拟Spring创建Bean和dom4j读取xml文件(视频学习传智播客Spring2.503)

      1 import java.beans.Introspector;
    2 import java.beans.PropertyDescriptor;
    3 import java.lang.reflect.Method;
    4 import java.net.URL;
    5 import java.util.ArrayList;
    6 import java.util.HashMap;
    7 import java.util.List;
    8 import java.util.Map;
    9
    10 import org.apache.commons.beanutils.ConvertUtils;
    11 import org.dom4j.Document;
    12 import org.dom4j.Element;
    13 import org.dom4j.XPath;
    14 import org.dom4j.io.SAXReader;
    15
    16
    17 public class ItcastClassPathXMLApplicationContext {
    18 List<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>();
    19 Map<String, Object> beans=new HashMap<String, Object>();
    20 public ItcastClassPathXMLApplicationContext(String path) {
    21 // TODO Auto-generated constructor stub
    22 this.readXML(path);
    23 initialBeans();
    24 injectBeans();
    25 }
    26 private void injectBeans() {
    27 // TODO Auto-generated method stub
    28 //必须在注入之前先实例化好每一个Bean
    29 for(BeanDefinition bd:beanDefinitions){
    30 Object bean=getBean(bd.getId());
    31 if(bean!=null){
    32 //注入依赖
    33 try {
    34 //取得Bean的属性描述
    35 PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
    36 for(PropertyDefinition pd:bd.getProperties()){
    37 //pd中的name是否存在于Bean的属性中
    38 for(PropertyDescriptor d:pdps){
    39 if(d.getName().equals(pd.getName())){
    40 //取得setter方法
    41 Method setter=d.getWriteMethod();//private方法也会出错
    42 Object value=null;
    43 if(setter!=null){
    44 if(pd.getRef()!=null && !pd.getRef().equals("")){
    45 value=getBean(pd.getRef());
    46 }else{
    47 value=ConvertUtils.convert(pd.getValue(), d.getPropertyType());
    48 }
    49 }
    50 setter.setAccessible(true); //设置允许访问
    51 setter.invoke(bean,value);
    52 break;
    53 }
    54 }
    55 }
    56 } catch (Exception e) {
    57 // TODO Auto-generated catch block
    58 e.printStackTrace();
    59 }
    60
    61 }
    62 }
    63 }
    64 private void initialBeans() {
    65 // TODO Auto-generated method stub
    66 for(BeanDefinition b:beanDefinitions){
    67 if(b.getClassName()!=null&& !b.getClass().equals(""))
    68 try {
    69 beans.put(b.getId(), Class.forName(b.getClassName()).newInstance());
    70 } catch (Exception e) {
    71 e.printStackTrace();
    72 }
    73 }
    74 }
    75 /**
    76 * 读取xml配置文件
    77 * @param path
    78 */
    79 private void readXML(String path) {
    80 // TODO Auto-generated method stub
    81 SAXReader reader=new SAXReader();//创建读取器
    82 URL url=getClass().getClassLoader().getResource(path);
    83 Document doc=null;
    84 try {
    85 doc=reader.read(url);
    86 //存放命名空间
    87 Map<String,String> nsps=new HashMap<String,String>();
    88 nsps.put("ns", "http://www.springframework.org/schema/beans");
    89 XPath ePath=doc.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
    90 ePath.setNamespaceURIs(nsps);
    91 List<Element> eList=ePath.selectNodes(doc);//获取文档下所有bean节点
    92 for(Element e:eList){
    93 String id=e.attributeValue("id");
    94 String className=e.attributeValue("class");
    95
    96 BeanDefinition bDefinition=new BeanDefinition(id, className);
    97 //读取property
    98 XPath pXPath=e.createXPath("ns:property");//当前元素
    99 pXPath.setNamespaceURIs(nsps);
    100 List<Element> pros=pXPath.selectNodes(e);
    101 for(Element e2:pros){
    102 String name=e2.attributeValue("name");
    103 String ref=e2.attributeValue("ref");
    104 String value=e2.attributeValue("value");
    105
    106 //System.out.println(name+" "+ref);
    107 PropertyDefinition pd=new PropertyDefinition(name, ref,value);
    108 bDefinition.getProperties().add(pd);
    109 }
    110 beanDefinitions.add(bDefinition);
    111 }
    112 } catch (Exception e) {
    113 // TODO Auto-generated catch block
    114 e.printStackTrace();
    115 }
    116 }
    117 public Object getBean(String id){
    118 return beans.get(id);
    119 }
    120 }
    
    

     加入注解解析功能:

    定义注解:

     1 import java.lang.annotation.ElementType;
    2 import java.lang.annotation.Retention;
    3 import java.lang.annotation.RetentionPolicy;
    4 import java.lang.annotation.Target;
    5
    6 //表示使用的范围,编译器、运行期
    7 @Retention(RetentionPolicy.RUNTIME)
    8 //注解可以加入的位置
    9 @Target({ElementType.FIELD,ElementType.METHOD})
    10 public @interface ItcastResource {
    11 String name() default "";
    12 }

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

     1 private void annotationInject() {
    2 // TODO Auto-generated method stub
    3 for(BeanDefinition bd:beanDefinitions){
    4 Object bean=getBean(bd.getId());
    5 if(bean!=null){
    6 try {
    7 //取得所有的属性
    8 PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
    9 for(PropertyDescriptor pdesc:pdps){
    10 //判断setter上是否存在注解
    11 Method setter=pdesc.getWriteMethod();
    12 if(setter!=null&& setter.isAnnotationPresent(ItcastResource.class)){
    13 //取出注解的name属性
    14 ItcastResource itRes=setter.getAnnotation(ItcastResource.class);
    15 Object value=null;
    16 if(itRes.name()!=null&&!itRes.name().equals("")){
    17 value=getBean(itRes.name());
    18 }else{
    19 //取得属性的名称
    20 value=getBean(pdesc.getName());
    21 if(value==null){//按类型找
    22 //遍历所有的bean
    23 for(String key:beans.keySet()){
    24 //类型匹配
    25 if(pdesc.getPropertyType().isAssignableFrom(beans.get(key).getClass())){
    26 value=beans.get(key);
    27 break;
    28 }
    29
    30 }
    31 }
    32 }
    33 setter.setAccessible(true);
    34 setter.invoke(bean, value);
    35 }
    36 }
    37 //取得字段
    38 Field[] fields=bean.getClass().getDeclaredFields();
    39 for(Field f:fields){
    40 //是否存在注解
    41 if(f.isAnnotationPresent(ItcastResource.class)){
    42 ItcastResource itRes=f.getAnnotation(ItcastResource.class);
    43 Object value=null;
    44 if(itRes.name()!=null&&!itRes.name().equals("")){
    45 value=getBean(itRes.name());
    46 }else{
    47 //取得属性的名称
    48 value=getBean(f.getName());
    49 if(value==null){//按类型找
    50 //遍历所有的bean
    51 for(String key:beans.keySet()){
    52 //类型匹配
    53 if(f.getType().isAssignableFrom(beans.get(key).getClass())){
    54 value=beans.get(key);
    55 break;
    56 }
    57
    58 }
    59 }
    60 }
    61 f.setAccessible(true);
    62 f.set(bean, value);
    63 }
    64 }
    65 } catch (Exception e) {
    66 // TODO Auto-generated catch block
    67 e.printStackTrace();
    68 }
    69
    70 }
    71 }
    72 }



  • 相关阅读:
    分享一个Fluent风格的邮件发送封装类
    写一个ActionFilter检测WebApi接口请求和响应
    一道有趣的面试题,小鸟和火车的问题
    Centos7 查看Mysql配置文件
    Centos7 grep命令简介
    Centos7 网络配置
    django之python3.4及以上连接mysql的一些问题记录
    NetCore log4net 集成以及配置日志信息不重复显示或者记录
    ionic3中关于Ionic ui component使用的一些总结
    ionic2升级到ionic3并打包APK
  • 原文地址:https://www.cnblogs.com/tazi/p/2306575.html
Copyright © 2011-2022 走看看