模拟Spring的简单实现

项目结构如下:

如何思考?面向抽象编程?
先来看看一个序列图

从以上看出了什么?初学的,能看得出是什么才怪,那不管它了。看看具体实现吧

首先要建立一个实体类:User,放在model包下

package com.wwj.model; 

/**
 * 实体类
 * @author wwj
 * Spring
 */
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;
  }
} 

下面就是叫你如何面向抽象编程,简单来说如何面向接口编程,下面定义一个接口

package com.wwj.dao; 

import com.wwj.model.User; 

/**
 * 面向抽象编程
 * @author wwj
 * 优点:增加了灵活性
 */
public interface UserDAO {
  public void save(User user);
} 

可以很清楚看到,这个接口声明了一个方法,save方法,里面有一个参数User对象,我们可以想到它是可以用来保存User对象到数据库里去的。

把具体实现交给实现类

package com.wwj.dao.impl; 

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

/**
 * 接口实现类
 * @author wwj
 *
 */
public class UserDAOImpl implements UserDAO{ 

  @Override
  public void save(User user) {
    System.out.println("save user");
  } 

}

这样做的好处是,如果你要更换数据库环境,你就能灵活定义不同的数据库代码了。
怎么调用以上的方法,为了使业务逻辑和数据库操作分离开,我们需要定义一个业务逻辑类

package com.wwj.service; 

import com.wwj.dao.UserDAO;
import com.wwj.dao.impl.UserDAOImpl;
import com.wwj.model.User; 

/**
 * 服务类,实现业务逻辑
 * @author wwj
 *
 */
public class UserService {
  private UserDAO userDAO; 

  public UserDAO getUserDAO() {
    return userDAO;
  } 

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

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

我们可以看到,上面有一个东西,东西?UserDAO啊,看到它的作用了没有,看到才怪。这里设计到一个IOC也叫做DI的概念,中文意思叫做依赖注入,也叫控制反转,这在Spring是一个很重要的概念,要把它弄懂,才能很好的理解Spring的原理。

下面真正模拟Spring的实现,有点像工厂模式,利用Spring,我们可以把不同对象装配在一起使用。
先看一下配置文件beans.xml

<beans>
  <bean id="u" class="com.wwj.dao.impl.UserDAOImpl" />
  <bean id="userService" class="com.wwj.service.UserService" >
    <property name="userDAO" bean="u"/>
  </bean>
</beans>

一个工厂方法

package com.wwj.spring; 

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

一个解析xml文件的类,并实现BeanFactory

package com.wwj.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; 

public class ClassPathXmlApplicationContext implements BeanFactory{
  //定义一个容器,用来存放对象
  private Map<String,Object> beans = new HashMap<String, Object>(); 

  public ClassPathXmlApplicationContext() throws Exception{
    SAXBuilder sb = new SAXBuilder();
    Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
    Element root = doc.getRootElement();  //获取根结点
    List list = root.getChildren("bean");  //取名为bean的所有元素
    for(int i = 0; i < list.size(); i++) {
      Element element = (Element) list.get(i);
      String id = element.getAttributeValue("id");  //取id值
      String cla = element.getAttributeValue("class"); //取class值
      Object o = Class.forName(cla).newInstance();
      System.out.println(id);
      System.out.println(cla);
      beans.put(id,o); 

      for(Element propertyElement : (List<Element>)element.getChildren("property")){
        String name = propertyElement.getAttributeValue("name");  //UserDAO
        String bean = propertyElement.getAttributeValue("bean");  //u
        Object beanObject = beans.get(bean);//UserDAOImpl instance 

        //拼凑方法名,实现setUserDAO方法
        String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
        System.out.println("method name = " + methodName); 

        //利用反射机制获取方法对象
        Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
        m.invoke(o, beanObject);  //调用方法
      } 

    } 

  } 

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

}

来一个测试类

package com.wwj.service; 

import org.junit.Test; 

import com.wwj.model.User;
import com.wwj.spring.BeanFactory;
import com.wwj.spring.ClassPathXmlApplicationContext; 

/**
 * 单元测试类
 * @author wwj
 *
 */
public class UserServiceTest { 

  @Test
  public void testAdd() throws Exception{
    BeanFactory beanFactory = new ClassPathXmlApplicationContext(); 

    UserService service =(UserService)beanFactory.getBean("userService");
    User u = new User();
    service.add(u);
  } 

}

从测试类我们可以看出点端倪了,首先定义一个BeanFactory对象,通过这个对象调换用其getBean的方法,获取业务逻辑类对象,后面就可以通过调用这个服务类的add方法把user对象添加到数据库中去。当然这里没有实现插入数据库,只是简单的实现了测试。其实整个过程很明了的,Spring的核心配置文件,将对象控制起来了,当要使用的时候就将对象注入到服务类当中去,服务类就可以利用DAO层的对象,进行数据库相关的操作。

以上就是整理的网上关于spring配置内容,希望可以对大家有所帮助。

(0)

相关推荐

  • 读取spring配置文件的方法(spring读取资源文件)

    1.spring配置文件 复制代码 代码如下: <bean id="configproperties"          class="org.springframework.beans.factory.config.PropertiesFactoryBean">          <property name="location" value="classpath:jdbc.properties"/>

  • 手把手教你使用flex eclipse整合spring

    最先下载FlashBuilder_4_7_LS10_win64.exe试了几个eclipse安装插件都没成功,包括myeclipse8.5.spring sts2.9.2.eclipse3.5.j2eeeclipse版本4.2.0,后来搞了一个FlashBuilder_4_LS10.exe安装完找不到插件安装文件原来这个是单独版,必须插件版才行,最后下载FlashBuilder_4_Plugin_LS10.exe终于配置成功了,myeclipse8.5不行,spring sts可以了. spri

  • spring aop两种配置方式

    第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步: 1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Before, @AfterReturning,@After,@AfterThrowing,@Around). 2. 开发需要被拦截的类. 3. 将切面配置到xml中,当然,我们也可以使用自动扫描Bean的方式.这样的话,那就交由Spring AoP容器管理. 另外需要引用 aspectJ 的 jar 包:

  • 解决springmvc+mybatis+mysql中文乱码问题

    近日使用ajax请求springmvc后台查询mysql数据库,页面显示中文出现乱码 最初在mybatis配置如下 <select id="queryContentById" resultType = "java.lang.String" parameterType="String" > select text from News where id=#{o} </select> 其中表News的text字段为blob类型

  • SpringMVC文件上传 多文件上传实例

    必须明确告诉DispatcherServlet如何处理MultipartRequest.SpringMVC中提供了文件上传使用方式如下配置xxx-servlet.xml,添加如下代码: 复制代码 代码如下: <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">          <!-- 设置

  • Spring中的事务管理实例详解

    本文实例讲述了Spring中的事务管理.分享给大家供大家参考.具体分析如下: 事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用 事务的四个关键属性(ACID) ① 原子性(atomicity):事务室一个原子操作,有一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用 ② 一致性(consistency):一旦所有事务动作完成,事务就被提交.数据和资源就

  • java Spring整合Freemarker的详细步骤

    我的開發環境框架:springmvc開發工具:springsource-tool-suite-2.9.0版本:1.6.0_29tomcat版本:apache-tomcat-7.0.26前言:FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP.它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等.簡而言之,Freemarker就是在Jave Web開發

  • Spring MVC中上传文件实例

    SpringMVC(注解)上传文件需要注意的几个地方: 1.form的enctype="multipart/form-data",这个是上传文件必须的 2.applicationContext.xml配置: 复制代码 代码如下: <!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 --> <bean id="multipartResolver" class="org.springframework.w

  • spring快速入门实例教程

    本文实例讲述了spring的基本配置与控制反转.分享给大家供大家参考.具体如下: 这里我们采用了maven构建java项目,没有采用maven的同样适用. 1. 创建maven项目,我创建的项目名称为springdemo. 2. 添加依赖包,我是通过maven添加的包,maven相关配置如下: 复制代码 代码如下: <dependency>     <groupId>org.springframework</groupId>     <artifactId>

  • Spring MVC 框架搭建配置方法及详解

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理. 一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.comm

  • Spring常用注解汇总

    本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下: 使用注解之前要开启自动扫描功能 其中base-package为需要扫描的包(含子包). <context:component-scan base-package="cn.test"/> @Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean. @Scope注解 作用域 @Lazy(true) 表示延迟初始化 @Service用于

  • SpringMVC+MyBatis声明式事务管理

    采用的基本搭建环境:SpringMVC.MyBatis.MySQL.tomcat Spring事务管理分解了传统的全局事务管理和本地事务管理的劣势,使得在任何环境中都可以使用统一的事务管理模型,你可以写一次代码,然后在不同的环境从你的代码里面配置不同的事务管理策略,Spring提供两种事务管理策略:一种是声明式事务管理策略,另一种是编程式事务管理策略,这里主要介绍声明式事务管理策略 由于采用的是SpringMVC. MyBatis,故统一采用了标注来声明Service.Controller 由于

随机推荐