模拟Spring

1.常规的类管理方式是:1.使用动态代理将业务逻辑的实现类构建出来,Dao jdkProxy= (Dao) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{Dao.class}, new NiuInvocationHandler(new DaoImpl()));然后执行相应的业务逻辑。
2.将把类放入工厂中,让工厂进行处理。

使用dom4j 获取XML文件

官网:https://dom4j.github.io/
1.获取document:

public class Foo {

    public Document parse(URL url) throws DocumentException {
    //SAXReader 是Dom4j提供用于读取XML的操作类
        SAXReader reader = new SAXReader();
        //Document存储了读取进来的XML文档的内容
        Document document = reader.read(url);
        return document;
    }
}

document:{A document can be navigated using a variety of methods that return standard Java Iterators}document能够使用不同的方法来返回标准的java迭代器去导航需要的地方(或者节点)

 Element root = document.getRootElement();

    // iterate through child elements of root
    for (Iterator<Element> it = root.elementIterator(); it.hasNext();) {
        Element element = it.next();
        // do something
    }

根据Element获取Attribute

 Attribute attributeId= element.attribute("id");
 String beanName= attributeId.getValue();
 

模拟一个简单Spring

先模拟一个工具类

package com.org.spring.util;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class BeanFactory {

    Map map=new HashMap<String,Object>();

    //解析XML技术
    public BeanFactory(String Xml) {

        parseXml(Xml);
    }

    //用于读取XML文件
    public void parseXml(String xml)throws NiuSpringException{
        File file=new File(this.getClass().getResource("/").getPath()+"//"+xml);
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(file);
             Element elementRoot= document.getRootElement();
            List<Element> allChild=elementRoot.elements();
            Attribute attribute=  elementRoot.attribute("default");
            boolean flag=false;
            if (attribute!=null){
                flag=true;
            }
            for (Iterator<Element> itFirst = elementRoot.elementIterator(); itFirst.hasNext();) {
                //实例化对象
                Element elementFirstChiled = itFirst.next();

                //获取配置文件中bean中id的名称
                Attribute attributeId= elementFirstChiled.attribute("id");
                String beanName= attributeId.getValue();
                //获取配置文件中bean中具体的实现类
                Attribute attributeClass= elementFirstChiled.attribute("class");
                String calzzName= attributeClass.getValue();
                Class clazz=Class.forName(calzzName);


                //1.使用的Set方法进行注入的
                // 获取当前bean中有没有property属性,也就是获取第二层的内容
                Object object=null;
                for (Iterator<Element> itSecond = elementFirstChiled.elementIterator(); itSecond.hasNext();) {
                    /**
                     * 通过ref获得Value,得到它依赖对象的Bean的名称。
                     * 根据Value的值获取一个Failed对象。
                     * 通过Failed的set的方法,去set那个对象
                     * */

                    Element elementSecondChild=itSecond.next();
                    if (elementSecondChild.getName().equals("property")) {
                        System.out.println("走了吗手动");
                        object =clazz.newInstance();
                        //获取ref对应的bean,并得到相应的对象,
                        // 用于对当前类的相应的属性进行赋值。
                        String refValue=elementSecondChild.attribute("ref").getValue();
                       Object injetObject=  map.get(refValue);


                       //获取name中的属性名称也就是和当前类的set方法的名字一致
                        String nameValue=elementSecondChild.attribute("name").getValue();
                        Field field=clazz.getDeclaredField(nameValue);
                        //获取对应的set方法
                        field.setAccessible(true);
                        //field.set在指定的的对象上对当前属性进行赋值
                        // 第一个参数是当前对象的值,第二个参数是进行set赋值的类
                        field.set(object,injetObject);


                    }
                    //有构造方法时
                    else {
                        String refValue=elementSecondChild.attribute("ref").getValue();
                        Object injetObject=  map.get(refValue);


                        Class injectObjectClazz=injetObject.getClass();
                        //获取构造方法
                        Constructor constructor= clazz.getConstructor(injectObjectClazz.getInterfaces()[0]);
                        object= constructor.newInstance(injetObject);

                    }
                }

                //如果bean中有property,也就是手动装配了,则就不需要进行自动装配了
                //因为object在手动装配的时候会赋值,所以可以根据其是否为空进行判定
                if (object ==null) {
                    System.out.println("走了吗");
                    if (flag) {
                        if (attribute.getValue().equals("byType")) {
                            //判断是否依赖,也就是获取当前类是否有属性
                            Field fields[] = clazz.getDeclaredFields();
                            for (Field field : fields) {
                                //获得属性的类型
                                Class injectObjectClazz = field.getType();
                                /**
                                 * 由于是byType,所有需要遍历map当中所有的对象
                                 * 找出和injectObjectClazz类型相同的对象
                                 * */
                                int count = 0;
                                Object injectObject = null;
                                for (Object key : map.keySet()) {
                                    //获取当前类中的接口,
                                    Class temp = map.get(key).getClass().getInterfaces()[0];
                                    //判断属性接口的名称和从Map中获得的名称一致
                                    if (temp.getName().equals(injectObjectClazz.getName())) {
                                        injectObject = map.get(key);
                                        //记录来找到一个,因为可能找到多个
                                        count++;
                                    }
                                }
                                if (count > 1) {
                                    throw new NiuSpringException("需要一个对象但是找到了两个对象");
                                } else {
                                    //现将当前对象New出来,然后把属性值拿出来
                                    object = clazz.newInstance();
                                    field.setAccessible(true);
                                    field.set(object, injectObject);
                                }
                            }
                        }
                    }
                }
                //初始化未被创建的对象,例如被依赖的对象
                if (object==null){
                    object=clazz.newInstance();
                }
                map.put(beanName,object);

            }

            //System.out.println(map);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //生成需要的对象
    public Object getBean(String beanName){
        return map.get(beanName);
    }
}

配置文件代码

<?xml version="1.0" encoding="UTF-8"?>

<!--
   1.那些类需要管理
   2.怎么告诉我 (写Bean标签)
   3.怎么维护他们的关系 setter construct
   4.怎么体现 setter或者 construct

-->
<beans default="byType">
    <bean id="dao" class="com.niu.dao.UserDaoImpl"></bean>
     <!--<bean id="dao1" class="com.niu.dao.UserDaoImpl1"></bean>-->
    <bean id="service" class="com.niu.service.UserServiceImpl">
        <!--setter方法-->
      <!-- <property name="dao1" ref="dao1"></property>-->
      <!--  <constructor-arg name="dao" ref="dao"></constructor-arg>-->
    </bean>

</beans>

定义一个异常类


public class NiuSpringException extends RuntimeException {
    public NiuSpringException(String msg){
        super(msg);
    }
}
public interface UserDao {
    public void query();
}


public class UserDaoImpl implements UserDao {
    public void query() {
        System.out.println("dao");
    }
}

public class UserServiceImpl implements UserSivice {
    UserDao dao1;

    /*public UserServiceImpl(UserDao dao) {
        this.dao = dao;
    }*/

    public void find() {
        System.out.println("service");
        dao1.query();
    }

   /* public void setDao(UserDao dao) {
        this.dao = dao;
    }*/
}
public interface UserSivice {
    public void find();
}

public class Test {
    public static void main(String[] args) {

        BeanFactory beanFactory=new BeanFactory("spring.xml");

        //通过beanFactory获取相应的Bean
        UserSivice userSivice= (UserSivice) beanFactory.getBean("service");
        userSivice.find();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值