手写spring+springmvc+mybatis框架篇——开篇

     我们平日开发时所用的SSM框架,可是你真的了解它吗?技术革新,换代应接不暇,只有理解了源码才能保证在技术快速更迭的时代中真正站稳脚跟。本系列文章抽丝剥茧,源码分析百度有很多,在这里只列举几个我收录的优秀的博客推荐给大家,本文不过多的分析源码,更注重将代码理解后的实现。 话不多说,开启正题。(由于本人是小白,理解的不深所以写出来的东西比较浅显易懂。如果有错误还望各位大佬指出来,帮助我提高)

    项目介绍:此项目是在手写SSM框架的基础上开发了一个简单的登录功能。

    首先是spring框架的实现,spring的依赖注入特性是集成其他所有框架的基础。在spring2.5版本之前,只支持配置文件注入。在2.5之后加入了@Autowired注解,实现了注解注入。我们的这个spring框架当然是都支持啦。首先是xml版本注入。目前支持的是构造器注入和set属性注入。

    实现思路:

    1.用dom4j解析xml文件。获取各个节点的属性和内容。

    2.用枚举定义IOC的bean的规则,用BeanFacorygetBean方法读取配置信息,如果xml读取到的属性和IOCRULES的枚举内容匹配的话,用BeanDefinitionMap对象保存,然后用反射实例化一个对象。

    3.读取在xml文件中读取到的扫包路径,扫描此路径下的有注解的类按照自下而上的顺序存储在componentList中。

    4.将componentList对象按照顺序实例化出对象。

    一些高大上的名词,其实就是一些对象或者数据结构。比如我们常说的spring容器其实就指的是一个map对象集合,在spring源码其实就是DefaultListableBeanFactory类中如下对象

private final Map beanDefinitionMap = new ConcurrentHashMap(256);

    将这些对象实例化之后就是我们说的注入。再比如springmvc中的handlerMapping,其实就是map集合,key是方法名,value是@RequestMapping的路径。再比如...还有很多,

    在实战之前我先提出几个我自己想到的问题,希望大家看的时候带着问题提来看。

    1.spring有xml配置,也有注解配置,那么先实例化的是哪种版本呢?

    2. 构造器注入,属性注入如何实现的?

    3. 在指定包的路径下有那么多要注入的bean,service层调用dao,所以dao层一定要在service之前注入,然后在service层属性注入的时候才能将dao层注入,那么如何保证实例化的顺序呢?这也是难点。

    4.我们使用的时候只需要用@Autowired标记接口,即可使用。但是我们知道接口并不能实例化对象,那么spring是如何做到的呢?而且有的接口有实现类,在mybatis中连实现类都没有,如何实现的呢?

效果图

手写spring+springmvc+mybatis框架篇——开篇_第1张图片

手写spring+springmvc+mybatis框架篇——开篇_第2张图片

   

下面开始实战:

项目必须用jdk1.8,不然会报错.里面一些方法只有1.8才有。

2 用到了lombok这个jar包,主要是简化了代码量,一个注解就可以省略getset方法。

3 解析xml用的dom4j,在小型xml文件的解析和操作中dom4j是最佳选择

4 在最后的demo中,RegisterServiceImpl,UserServiceImpl,RegisterService,UserService等文件没有真正的使用。只是考虑多层注入的时候,为了测试注入的顺序是否是对的。在dao层真正用的是UserMapper这个接口。

    先介绍一下工具类吧。省的代码中出现的时候大家看不懂

package spring.Utils;

/**
 * Created by Xiao Liang on 2018/6/27.
 * 注解工具类:判断注解是否为空
 */
public class  AnnotationUtils {
    public  static   boolean isEmpty(T t){
        return  t == null ? true : false;
    }
}

package spring.Utils;

/**
 * @ClassName ConvertUtis
 * @Description 根据传入的属性和类名,将属性名强转为类名的属性
 * @Data 2018/7/4
 * @Author xiao liang
 */
public class ConvertUtis {

    public static Object  convert(String className,String parameter){
        if (className.equals("String")){
            return parameter;
        }
        else if (className.equals("Integer")){
            return Integer.valueOf(parameter);
        }
        else if (className.equals("int")){
            return Integer.valueOf(parameter);
        }
        else if (className.equals("Float")){
            return Float.valueOf(parameter);
        }
        else if (className.equals("Double")){
            return Integer.valueOf(parameter);
        }
        else if (className.equals("Long")){
            return Long.valueOf(parameter);
        }
        else if (className.equals("Short")){
            return Short.valueOf(parameter);
        }
        else if (className.equals("Byte")){
            return Byte.valueOf(parameter);
        }
        else if (className.equals("Boolean")){
            return Boolean.valueOf(parameter);
        }
        return null;

    }
}
package spring.Utils;

/**
 * @ClassName GetMethodName
 * @Description 根据属性名拼接set方法
 * @Data 2018/7/4
 * @Author xiao liang
 */
public class GetMethodName {
    public   static  String getSetMethodNameByField(String propertyName) {
        String methodName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        return methodName;
    }
}
package spring.Utils;

/**
 * @ClassName isBasicType
 * @Description 判断是不是基本数据类型
 * @Data 2018/7/4
 * @Author xiao liang
 */
public class isBasicTypeUtils {
    public static boolean  isBasicType(String typeName){
        if (typeName.equals("String")){
            return true;
        }
        else if(typeName.equals("Integer")){
            return true;
        }
        else if(typeName.equals("int")){
            return true;
        }
        else if(typeName.equals("Long")){
            return true;
        }
        else if(typeName.equals("Short")){
            return true;
        }
        else if(typeName.equals("Float")){
            return true;
        }
        else if(typeName.equals("Double")){
            return true;
        }
        else if(typeName.equals("Byte")){
            return true;
        }
        return false;
    }
}
package spring.Utils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *  @Author xiao liang
 *  @Desprition 在链表中添加数据,添加时保证只有一个相同的实例
 */
public class ListAddUtils {
    public static  void add(List list ,T t) {
        Set set1 = new HashSet<>(list);
        if (set1.add(t)){
            list.add(t);
        }
    }
}
package spring.Utils;
/**
 *  @Author xiao liang
 *  判断字符串是否为空
 */
public class StringUtils {
    public static boolean isEmpty(String string) {
        if ((string == null) || "".equals(string)) {
            return true;
        }
        return false;
    }
}

还有一个常量类。

package spring.constants;

import spring.xml.FileSystemXmlApplicationContext;
/**
 * Created by Xiao Liang on 2018/6/27.
 * @Description :保存的是各个配置文件的路径
 */
public interface Constants {
    String PATH = FileSystemXmlApplicationContext.class.getResource("/").getPath();
    String contextConfigLocation = "application.xml";
    String springmvcConfigLocation = "spring-mvc.xml";
    String mybatisConfigLocation = "MyUserMapper.xml";
}

还有三个xml文件。application.xml



    
        
        
    
    
        
        
        
        
    

    
    

springmvc.xml



    
        
        
    

MyUserMapper.xml




    


这是一个maven项目,pom.xml文件内容如下




    4.0.0
    com.myspring
    start
    1.0-SNAPSHOT
    war
    start Maven Webapp
    
    http://www.example.com

    
        UTF-8
        1.8
        1.8
    

    
        
            junit
            junit
            4.11
            test
        

        
        
            org.projectlombok
            lombok
            1.18.0
            provided
        
        
        
            org.slf4j
            slf4j-api
            1.7.25
        

        
            org.slf4j
            slf4j-simple
            1.7.25
        


        
            javax.servlet
            servlet-api
            2.5
        

        
            javax.servlet.jsp
            jsp-api
            2.1.3-b06
        

        
            dom4j
            dom4j
            1.6.1
        

        
        
            jstl
            jstl
            1.2
        
        
        
            mysql
            mysql-connector-java
            5.1.8
        


    

    
        start
        
            
                
                    maven-clean-plugin
                    3.0.0
                
                
                
                    maven-resources-plugin
                    3.0.2
                
                
                    maven-compiler-plugin
                    3.7.0
                
                
                    maven-surefire-plugin
                    2.20.1
                
                
                    maven-war-plugin
                    3.2.0
                
                
                    maven-install-plugin
                    2.5.2
                
                
                    maven-deploy-plugin
                    2.8.2
                
            
        
    

下面是项目的业务逻辑代码,可以过一下,就是最简单的三层架构。业务逻辑代码中中有一些为了测试用,并没有实际的意义

package spring.demo.controller;

import spring.annotation.MyAutowired;
import spring.annotation.MyController;
import spring.annotation.MyModelAttribute;
import spring.annotation.MyRequestMapping;
import spring.dataObject.User;
import spring.demo.service.UserService;
import spring.springmvc.MyModelAndView;
import spring.springmvc.MyModelMap;
import spring.xmlRules.RequestMethod;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
@MyController
public class LoginController {

    @MyAutowired
    private UserService userService;
    //测试用的@MyRequstParam(value = "userName") String userName,  @MyRequstParam(value = "passWord") Integer passWord
    //返回值只支持MyModelAndView,数据模型和视图模型相结合
    @MyRequestMapping(value = "/hello", method = RequestMethod.POST)
    public MyModelAndView login(@MyModelAttribute("User") User user) {
        MyModelAndView myModelAndView = new MyModelAndView("success");
        MyModelMap myModel = new MyModelMap();
        User user1 = userService.queryUser("admin", "admin");
        myModel.addAttribute("test", user1.getUserName());
        myModelAndView.setModelMap(myModel);
        return myModelAndView;
    }
    @MyRequestMapping("/hello22")
    public String test() {
        return "success";
    }
}
package spring.demo.controller;

import spring.annotation.MyAutowired;
import spring.annotation.MyController;
import spring.annotation.MyRequestMapping;
import spring.demo.service.RegisterService;
import spring.demo.service.UserService;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
@MyController
public class RegisterController {
    @MyAutowired
    private UserService userService;
    @MyAutowired
    private RegisterService registerService;
    @MyRequestMapping("/register")
    public void regeister(){
        userService.queryUser("","");
        registerService.register();
    }
}
package spring.demo.service;

import spring.dataObject.User;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
public interface UserService {
     User queryUser(String userName, String passWord);
}
package spring.demo.service;

/**
 * Created by Xiao Liang on 2018/6/27.
 */
public interface RegisterService {
    void register();
}
package spring.demo.service.impl;

import spring.annotation.MyAutowired;
import spring.annotation.MyService;
import spring.dataObject.User;
import spring.demo.repository.RegisterDao;
import spring.demo.repository.UserDao;
import spring.demo.repository.UserMapper;
import spring.demo.service.UserService;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
@MyService
public class UserServiceImpl implements UserService {
    @MyAutowired
    private UserDao userDao;
    @MyAutowired
    private RegisterDao registerDao;
    @MyAutowired
    private UserMapper userMapper;
    @Override
    public User queryUser(String userName, String passWord) {
        return userMapper.queryUser(userName,passWord);
    }
}

package spring.demo.service.impl;

import spring.annotation.MyAutowired;
import spring.annotation.MyService;
import spring.demo.repository.RegisterDao;
import spring.demo.service.RegisterService;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
@MyService
public class RegisterServiceImpl implements RegisterService{
    @MyAutowired
    private RegisterDao registerDao;
    @Override
    public void register() {
        registerDao.register();
    }
}
package spring.demo.repository;

/**
 * Created by Xiao Liang on 2018/6/27.
 */
public interface UserDao {
      void test();
}
package spring.demo.repository;

/**
 * Created by Xiao Liang on 2018/6/27.
 */
public interface RegisterDao {
     void register();
}
package spring.demo.repository.impl;

import spring.annotation.MyRepository;
import spring.demo.repository.UserDao;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
@MyRepository
public class UserDaoImpl implements UserDao {
    @Override
    public void test() {
        System.out.println("我是UserDao");
    }
}
package spring.demo.repository.impl;

import spring.annotation.MyRepository;
import spring.demo.repository.RegisterDao;
/**
 * Created by Xiao Liang on 2018/6/27.
 */
@MyRepository
public class RegisterDaoImpl implements RegisterDao{
    @Override
    public void register() {
        System.out.println("我是RegisterDao");
    }
}
package spring.demo.repository;

import spring.dataObject.User;
/**
 * @ClassName UserMapper
 * @Description
 * @Data 2018/7/7
 * @Author xiao liang
 */
public interface UserMapper {
    User queryUser(String userName,String passWord);
}


我将此项目上传到了github,需要的童鞋可以自行下载。

https://github.com/836219171/MySSM



你可能感兴趣的:(框架)