`

模拟spring

阅读更多

需求:

把用户信息进行持久化。

分析:

1、提取需求中的实体类:用户信息,定义类:User,包含name和age两个field

2、分层。根据需求可分为用户服务和持久化层;

一、传统方法实现:

1、写持久层测试用例

package com.gll.spring.ioc.dao;

import com.gll.spring.ioc.model.User;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

/**
 * Created by Administrator on 2015/4/4.
 */
public class UserDaoTest {
    @Test
    public void should_return_true_when_save_user() throws Exception {

        UserDao userDao = new UserDao();

        User user = new User();

        assertThat(userDao.save(user),is(true));
    }
}

 3、消除测试用例中的错误,创建实体类User和持久化类DaoUser,并运行测试用例并通过:

package com.gll.spring.ioc.model;

/**
 * Created by Administrator on 2015/4/4.
 */
public class User {

    private String name;

    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

 

package com.gll.spring.ioc.dao;

import com.gll.spring.ioc.model.User;

/**
 * Created by Administrator on 2015/4/4.
 */
public class UserDao {
    public boolean save(User user) {
        return true;
    }
}

4、先写服务层测用例,消除用例中的错误并使用例通过,代码如下:

  

package com.gll.spring.ioc.service;

import com.gll.spring.ioc.dao.UserDao;
import com.gll.spring.ioc.model.User;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

/**
 * Created by Administrator on 2015/4/4.
 */
public class UserServiceTest {

    @Test
    public void should_return_true_when_add_user() throws Exception {

        UserService userService = new UserService();

        userService.setUserDao(new UserDao());
        
        User user = new User();
        assertThat(userService.add(user),is(true));
    }
}

  

package com.gll.spring.ioc.service;

import com.gll.spring.ioc.dao.UserDao;
import com.gll.spring.ioc.model.User;

/**
 * Created by Administrator on 2015/4/4.
 */
public class UserService {
    private UserDao userDao;

    public boolean add(User user) {
        return userDao.save(user);
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

 5、完成需求,问题:

      需求变更:用户信息存储到多个数据库或文件中时,则需要修改代码,由开发者控制实现。

二、模拟spring实现

1、考虑在配置文件中配置Dao的具体实现类,增加一个接口BeanFactory:

package com.gll.spring.simulation;

/**
 * Created by Administrator on 2015/4/4.
 */
public interface BeanFactory {

    Object getBean(String var);
}

 

2、定义配置文件simulation.xml,格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="userDao" class="com.gll.spring.ioc.dao.UserDao"></bean>
    <bean id="userService" class="com.gll.spring.ioc.service.UserService">
        <property name="userDao" ref="userDao"></property>
    </bean>
</beans>

 3、写一个解析simulation.xml文件的测试用例

package com.gll.spring.simulation;

import com.gll.spring.ioc.dao.UserDao;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

/**
 * Created by Administrator on 2015/4/4.
 */
public class ClassPathXmlApplicationContextTest {
    @Test
    public void should_return_class_UserDao_when_get_bean_by_userDao() throws Exception {

        BeanFactory ctx = new ClassPathXmlApplicationContext();

        assertThat(ctx.getBean("userDao").getClass().getName(),is(UserDao.class.getName()));
    }
}

 4、消除测试用例中的错误,运行测试用例,此时用例不通过,实现解析simulation.xml文件直到用例通过:

package com.gll.spring.simulation;

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

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2015/4/4.
 */
public class ClassPathXmlApplicationContext implements BeanFactory {

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

    public ClassPathXmlApplicationContext() throws Exception {

        SAXBuilder builder = new SAXBuilder();
        Document build = builder.build(this.getClass().getClassLoader().getResourceAsStream("simulation.xml"));
        Element rootElement = build.getRootElement();

        List<Element> elements = rootElement.getChildren("bean");

        for (int i = 0; i < elements.size(); i++) {

            Element element = elements.get(i);
            String id = element.getAttributeValue("id");
            String clazz = element.getAttributeValue("class");

            Object instance = Class.forName(clazz).newInstance();

            beans.put(id, instance);
        }
    }

    @Override
    public Object getBean(String var) {
        return beans.get(var);
    }
}

 5、写第二个测试用例,把UserDao注入到UserService中:

    @Test
    public void userDao_not_null_when_get_userDao_in_userService() throws Exception {

        UserService userService = (UserService) ctx.getBean("userService");

        assertThat(userService.getUserDao().getClass().getName(), is(UserDaoImpl.class.getName()));
    }

 该过程需要把UserDao提取成一个接口,实现setter注入,运行所有测试用例,直到所有测试通过:

package com.gll.spring.simulation;

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

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

/**
 * Created by Administrator on 2015/4/4.
 */
public class ClassPathXmlApplicationContext implements BeanFactory {

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

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

    public ClassPathXmlApplicationContext() throws Exception {

        SAXBuilder builder = new SAXBuilder();
        Document build = builder.build(this.getClass().getClassLoader().getResourceAsStream("simulation.xml"));
        Element rootElement = build.getRootElement();

        List<Element> elements = rootElement.getChildren("bean");

        buildObjectDI(elements);
    }

    private void buildObjectDI(List<Element> elements) throws Exception {
        for (int i = 0; i < elements.size(); i++) {

            Element element = elements.get(i);
            String id = element.getAttributeValue("id");
            String clazz = element.getAttributeValue("class");

            Object instance = Class.forName(clazz).newInstance();

            beans.put(id, instance);

            List<Element> properties = element.getChildren("property");

            BuildSetterDI(instance, properties);
        }
    }

    private void BuildSetterDI(Object instance, List<Element> properties) throws Exception {
        for (int j = 0; j < properties.size(); j++) {

            Element property = properties.get(j);
            String name = property.getAttributeValue("name");
            String ref = property.getAttributeValue("ref");
            Object field = beans.get(ref);

            String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);

            Method method = instance.getClass().getMethod(methodName, field.getClass().getInterfaces()[0]);

            method.invoke(instance, field);
        }
    }
}

 6、如果用户信息写到文件中,则增加写文件类FileUserDaoImpl.java,修改配置simulation.xml则可。

 

说明:例子采用先写测试后写实现的方式开发但用例跨度有点大,整个过程还伴随了重构。

分享到:
评论

相关推荐

    以注解方式模拟Spring IoC AOP

    本篇将深入探讨如何通过注解方式来模拟Spring的这两种机制,帮助你理解其底层原理。 ### 1. 依赖注入(IoC) 依赖注入是Spring框架的核心特性之一,它通过反转对象创建和管理的控制权,使得应用程序组件之间的耦合...

    Java模拟spring实现

    在本文中,我们将探讨如何通过Java来模拟Spring框架的基本功能。Spring是一个广泛应用的开源框架,它主要为Java应用程序提供依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP...

    Spring简单模拟Spring容器

    标题中的“Spring简单模拟Spring容器”意味着我们将探讨Spring框架的核心特性——IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入),以及如何通过编程方式模拟Spring容器的工作原理。...

    模拟Spring的IOC

    **模拟Spring的IOC** 在Java世界中,Spring框架以其强大的依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IOC)能力,成为企业级应用开发的首选框架之一。理解并模拟Spring的IOC...

    java模拟spring ioc

    这篇博客“java模拟spring ioc”很可能是探讨如何在没有Spring框架的情况下,使用纯Java代码来实现类似Spring的IOC功能。以下将详细介绍Spring的IOC和DI概念以及如何模拟这些概念。 **依赖注入(Dependency ...

    模拟Spring IoC

    在这个模拟Spring IoC的项目中,我们可以深入理解以下几个关键知识点: 1. **容器的概念**:Spring IoC容器是管理对象及其依赖关系的核心组件。在这个模拟项目中,会有一个类或接口扮演容器的角色,负责创建对象、...

    模拟spring ioc过程

    这个"模拟spring ioc过程"的学习例子是基于Java语言的,旨在帮助理解Spring框架中的这两个核心概念。在Java工程中,我们通常会通过配置文件(如XML或Java配置类)来定义bean的定义和它们之间的依赖关系。在实际运行...

    java 解析xml,模拟spring框架ioc

    本教程将深入探讨如何模拟Spring框架的IOC(Inversion of Control,控制反转)功能,特别关注XML配置文件的解析。 首先,我们需要理解什么是IOC。控制反转是一种设计原则,它将对象的创建和管理从对象本身剥离出来...

    使用反射和注解模拟Spring的依赖注入

    这篇博客"使用反射和注解模拟Spring的依赖注入"探讨了如何通过基本的Java特性来实现类似Spring的功能。我们将深入探讨反射和注解这两个关键概念,以及它们如何在模拟依赖注入中发挥作用。 首先,让我们理解反射的...

    自己动手模拟spring

    【标题】:“自己动手模拟spring” 【描述】:在该主题中,我们将深入理解Spring框架的核心概念,并通过编码实践来模拟其工作原理。参考链接提供了一个CSDN博客文章,作者详细介绍了如何从零开始创建一个简易版的...

    模拟spring和工具jar包

    本资源名为“模拟spring和工具jar包”,其目的是为了帮助我们理解Spring框架的核心概念——依赖注入,并通过一个简化版的实现来学习这一机制。 依赖注入是Spring框架的核心特性之一,它允许我们在不直接创建对象的...

    简单模拟spring cglib代理

    现在,我们来详细探讨如何简单模拟Spring框架中的CGLIB代理。要进行模拟,首先需要了解CGLIB代理的核心实现原理,包括代理类的生成、方法拦截和回调机制等。 1. 代理类的生成 CGLIB使用Enhancer类来生成代理对象。...

    尚学堂_Spring_0100_模拟Spring

    《尚学堂_Spring_0100_模拟Spring》 在深入探讨Spring框架之前,我们需要先理解Spring的核心理念。Spring是一个开源的Java平台,它主要为构建企业级应用提供了全面的编程和配置模型。它的核心特性是依赖注入...

    简单模拟Spring的beanFactory

    本文将通过模拟Spring的`BeanFactory`来深入理解其工作原理,帮助开发者更好地掌握Spring的核心概念。 `BeanFactory`是Spring框架中最基础的bean管理容器,它是所有更高级别的容器(如`ApplicationContext`)的基类...

    模拟spring aop技术

    **模拟Spring AOP技术** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组件,它提供了一种在不修改源代码的情况下,通过代理模式来实现横切关注点(如日志、事务管理等)的...

    模拟Spring的依赖注入

    本篇文章将深入探讨如何通过Java代码来模拟Spring的依赖注入机制。 **依赖注入的概念** 依赖注入是一种设计模式,它允许对象在运行时获取其依赖项,而不是在构造函数或初始化方法中硬编码这些依赖项。这样做的好处...

    自己的代码模拟spring的依赖注入

    现在,我们将深入探讨如何通过自己的代码来模拟Spring的依赖注入。 首先,理解依赖注入的概念至关重要。依赖注入意味着组件不直接创建其依赖的对象,而是由外部实体(如Spring IoC容器)提供。这样做的好处是,我们...

    模拟Spring架构的简易实现

    "模拟Spring架构的简易实现"这个项目可能是为了理解和学习Spring框架的基本原理而创建的,它可能通过简单的代码来模拟Spring的一些核心功能。 首先,我们要理解Spring的核心概念。依赖注入是Spring最基础的设计模式...

    模拟spring ioc技术

    本篇文章将详细解析“模拟Spring IOC技术”的核心概念,并通过一个小Demo帮助你深入理解IOC的工作原理。 首先,我们来解释一下什么是IOC和DI。控制反转(IOC)是编程中的一个设计原则,它改变了对象获取依赖的方式...

Global site tag (gtag.js) - Google Analytics