JavaEE---------模拟Spring实现IOC

和马士兵老师那里学习来的,希望把自己的见解和大家分享一下

首先我们需要一个总体的概念,这是在做什么?

简单的说,就是把下面这个类似于Spring的beans.xml的xml给解析出来然后作为我们需要的属性值

这也是Ioc的大致概念

先看一下这个xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="user" class="com.bq.dao.UserDAOImpl" />
    <bean id="userService" class="com.bq.service.UserService">
        <property name="userDAO" bean="user" />
    </bean>
</beans>

比较简单

然后需要相应的实体类,DAO层及其实现,Service类(Hibernate必备知识)

User.java

package com.bq.model;

public class User {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }
}

UserDAO.java

package com.bq.dao;

import com.bq.model.User;

public interface UserDAO {
    public void save(User user);
}

UserDAOImpl.java

package com.bq.dao;

import com.bq.model.User;

public class UserDAOImpl implements UserDAO {

    @Override
    public void save(User user) {
        /*
         * 在这里我们完成一系列操作
         * * Struts 2 的Action调用这里
         * Hibernate访问数据库
         * others
         */
        System.out.println(user.toString());
        System.out.println("user saved!");
    }

}

UserService.java

package com.bq.service;

import com.bq.dao.UserDAO;
import com.bq.model.User;

public class UserService {
    private UserDAO userDAO;

    public void add(User user) {
        userDAO.save(user);
    }

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}

接下来就是如何真正解析xml了,我们用的是jdom库

先创建一个接口以便获得bean

BeanFactory.java

package com.bq.spring;

public interface BeanFactory {
    public Object getBean(String id);
}

然后就是核心类ClassPathXmlApplicationContext.java

package com.bq.spring;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

/**
 * @author 白强
 *
 */
public class ClassPathXmlApplicationContext implements BeanFactory {

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

    // IOC Inverse of Control DI Dependency Injection
    //直接构造方法中解析beans.xml,具体可参见jdom的使用方法
    public ClassPathXmlApplicationContext() throws Exception {
        SAXBuilder sb = new SAXBuilder();
        // 注意如何得到xml
        Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); // 构造文档对象
        Element root = doc.getRootElement();
        List list = root.getChildren("bean");
        
        for (int i = 0; i < list.size(); i++) {
            Element element = (Element) list.get(i);
            String id = element.getAttributeValue("id");
            String clazz = element.getAttributeValue("class");
            Object o = Class.forName(clazz).newInstance();
            System.out.println(id);
            System.out.println(clazz);
            //保存在一个HashMap<String, Object>中
            beans.put(id, o);
            //下来分别解析含有property属性值的节点
        for (Element propertyElement : (List<Element>) element.getChildren("property")) {
                String name = propertyElement.getAttributeValue("name"); // userDAO
                String bean = propertyElement.getAttributeValue("bean"); // user
                Object beanObject = beans.get(bean);// UserDAOImpl,通过下面这个bean的值可以得到对应的Class
                String methodName = "set" + name.substring(0, 1).toUpperCase()+ name.substring(1);//用字符串分解合并得到方法名称setUserDAO 
                System.out.println("method name = " + methodName);//打印出methodName
                Method m = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]);//得到具体方法名称
                System.out.println(m);//打印出具体的方法名称
                m.invoke(o, beanObject);//Java反射注入
            }

        }

    }

    public Object getBean(String id) {
        return beans.get(id);
    }

}

最后来一个测试类测试一下吧,就不用Junit了

Index.java

package com.bq.main;

import com.bq.model.User;
import com.bq.service.UserService;
import com.bq.spring.BeanFactory;
import com.bq.spring.ClassPathXmlApplicationContext;

/**
 * @author 白强
 *
 */
public class Index {
    public static void main(String[] args){
        try {
            BeanFactory applicationContext = new ClassPathXmlApplicationContext();    
            UserService service = (UserService)applicationContext.getBean("userService");
            User u = new User();
            u.setUsername("baiqiang");
            u.setPassword("Iloveyou");
            service.add(u);

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

打印结果如下


user
com.bq.dao.UserDAOImpl
userService
com.bq.service.UserService
method name = setUserDAO
public void com.bq.service.UserService.setUserDAO(com.bq.dao.UserDAO)
User [username=baiqiang, password=Iloveyou]
user saved!


是不是挺有意思的呢?

原文地址:https://www.cnblogs.com/bq12345/p/3220927.html