手写简易的SSM框架

手写简易的SSM框架

整体结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H2mrz77x-1615383298773)(H:\图片\2021-3-10.png)]


注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
/**
 * 给加了@Component注解的类都让Spring来管理
 */
public @interface Component {
    String value(); //组件名称
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
    String value() default "";
}

@Target({ElementType.FIELD}) //作用目标  属性
@Retention(RetentionPolicy.RUNTIME)
public @interface Qualifier {   //对象的注入
    String value();  //beanName bean在工厂容器中的名称
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Query {
    String value();//sql语句 查询
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Repository { //dao层
    String value();
}

@Target({ElementType.TYPE,ElementType.METHOD}) //作用在类和方法上
@Retention(RetentionPolicy.RUNTIME)
/**
 * 请求映射
 */
public @interface RequestMapping {
    String value();//请求地址
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Service {
    String value();
}

@Target({ElementType.FIELD}) //作用目标  属性
@Retention(RetentionPolicy.RUNTIME)
public @interface StringValue {
    String value(); //给String类型的属性加注解
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Update {
    String value();//sql语句  增删改
}

@Controller
@RequestMapping("/goods")          //请求地址
public class GoodsController {
    @Qualifier("goodsService")
    private GoodsService goodsService;

   @RequestMapping("/remove")
    public void remove(HttpServletRequest request, HttpServletResponse response){
       goodsService.remove(request.getParameter("id"));
        System.out.println("移除商品信息");
    }
    @RequestMapping("/add")
    public void add(HttpServletRequest request, HttpServletResponse response) throws IOException {
       System.out.println("添加商品信息"+request.getParameter("name"));
        response.getWriter().write("hello"+request.getParameter("name"));
   }
    @RequestMapping("/modify")
    public void modify(HttpServletRequest request, HttpServletResponse response){
        System.out.println("修改商品信息");
    }
    @RequestMapping("/list")
    public void list(HttpServletRequest request, HttpServletResponse response){
       List<Map<String,Object>> mapList=goodsService.list();
        System.out.println(mapList);
    }
}


@Controller()
public class MemberController {
    @Qualifier("memberService")
    private MemberService memberService01;
    @StringValue("05190120")
    private String vipNumber;
    public void add(){
        memberService01.add();
    }
}

@Repository("goodsDao")
public interface GoodsDao {
    @Update("delete from goods where id=?")
    Integer delete(String id);
    @Query("select * from goods")
    List<Map<String,Object>> selectAll();
}


@Repository("memberDao")
public interface MemberDao {
    void insert();
    void delete();
}

@Service("goodsService")
public class GoodsService {
    @Qualifier("goodsDao")
    private GoodsDao goodsDao;
    @Qualifier("memberDao")
    private MemberDao memberDao;
    public void remove(String id){
        goodsDao.delete(id);
    }

    public List<Map<String, Object>> list() {
       return goodsDao.selectAll();
    }
}


@Service("memberService")
public class MemberService {
    @Qualifier("memberDao")
    private MemberDao memberDao;
    public void add(){
        memberDao.insert();
    }
}

public class Dom4jUtil {
    private static SAXReader saxReader=new SAXReader();
    private Dom4jUtil(){
    }
    public static Element getRootElement(String classPathFileName){
        try {
            Document document = saxReader.read(Dom4jUtil.class.getClassLoader().getResourceAsStream(classPathFileName));
            return document.getRootElement();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }
}


public class JdbcUtils {
    static DruidDataSource dataSource;
    static {
        try {
            Properties prop=new Properties();
            prop.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
            dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(prop);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static QueryRunner getQueryRunner(){
       return new QueryRunner(dataSource);
    }
}

public class ContextLoadListener implements ServletContextListener {
    /**
     * Tomcat启动时执行
     * 在tomcat启动时加载(初始化)容器,其实就是创建容器中的对象
     * @param sce
     */
    public List<String> allClassNameList=new ArrayList<>();

    public Map<String,Object> beanFactory=new HashMap<>();
    //映射
    public Map<String, Method> handlerMapping=new HashMap<>();
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //1.扫描包(由使用者来配置)
        //读入需要扫描的包名
        Properties properties=new Properties();
        try {
            properties.load(DispatcherServlet.class.getClassLoader().getResourceAsStream("application.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        String basePackageName = properties.getProperty("scan-package");

        //把包名转换为classPath路径
        String basePackagePath=basePackageName.replaceAll("\\.","/");
        //扫描指定包下面的所有的类
        doScan(basePackagePath);

        //2.判断我们刚才扫描出来的类哪些加了@Component,@Controller,@Service,@Repository,把添加了这些注解的类创建对象,加入到Bean的工厂中
        for (String className : allClassNameList) {
            try {
                Class<?> clazz = Class.forName(className);
                if (clazz.isAnnotationPresent(Component.class)) {//类上面是否加了Component注解
                    String beanName = clazz.getAnnotation(Component.class).value();   //getAnnotation()方法,返回该元素的指定类型的注解
                    beanFactory.put(beanName, clazz.newInstance()); //newInstance()方法来创建对象,使用类加载机制
                }
                if (clazz.isAnnotationPresent(Controller.class)) {
                    String beanName = clazz.getAnnotation(Controller.class).value();

                    if ("".equals(beanName)) {
                        char[] simpleNameArray = clazz.getSimpleName().toCharArray();
                        simpleNameArray[0] += 32;
                        beanName = new String(simpleNameArray);
                    }
                    beanFactory.put(beanName, clazz.newInstance());
                }
                if (clazz.isAnnotationPresent(Service.class)) {
                    String beanName = clazz.getAnnotation(Service.class).value();
                    beanFactory.put(beanName, clazz.newInstance());
                }
                if (clazz.isAnnotationPresent(Repository.class)) {
                    String beanName = clazz.getAnnotation(Repository.class).value();
                    Object obj=Proxy.newProxyInstance(ContextLoadListener.class.getClassLoader(), new Class[]{clazz}, new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            if(method.isAnnotationPresent(Query.class)){
                                //查询操作
                                String sql = method.getAnnotation(Query.class).value();
                                List<Map<String, Object>> mapList = JdbcUtils.getQueryRunner().query(sql, new MapListHandler());
                                return mapList;
                            }
                            if(method.isAnnotationPresent(Update.class)){
                                //增删改操作
                                String sql = method.getAnnotation(Update.class).value();
                                int update = JdbcUtils.getQueryRunner().update(sql,args);
                                return update;
                            }
                            return null;
                        }
                    });
                    beanFactory.put(beanName, obj);
                }
            }catch (ClassNotFoundException e){
                e.printStackTrace();
            }catch (InstantiationException e){
                e.printStackTrace();
            }catch (IllegalAccessException e){
                e.printStackTrace();
            }
        }
        //3.依赖注入
        beanFactory.forEach((beanName,obj)->{
            Field[] declaredFields = obj.getClass().getDeclaredFields();//getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和protected,但是不包括父类的声明字段
            for (Field declaredField : declaredFields) {
                try{
                    declaredField.setAccessible(true);//强吻  对私有的访问和赋值
                    //注入的是普通的String类型的value值
                    if(declaredField.isAnnotationPresent(StringValue.class)){
                        declaredField.set(obj,declaredField.getAnnotation(StringValue.class).value());
                    }
                    //注入的是对象
                    if(declaredField.isAnnotationPresent(Qualifier.class)){
                        String bName = declaredField.getAnnotation(Qualifier.class).value();
                        Object o= beanFactory.get(bName);
                        declaredField.set(obj,o);
                    }
                }catch (IllegalAccessException e){
                    e.printStackTrace();
                }
            }
        });
        //4.解析包含@Controller注解的类里面的方法,看哪些方法上面有@RequestMapping
        beanFactory.forEach((beanName,obj)->{
            if (obj.getClass().isAnnotationPresent(Controller.class)) {
                String baseUrl="";
                //解析Controller上面有无@RequestMapping
                if(obj.getClass().isAnnotationPresent(RequestMapping.class)){
                    baseUrl = obj.getClass().getAnnotation(RequestMapping.class).value();
                }
                Method[] declaredMethods = obj.getClass().getDeclaredMethods();
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        String url = declaredMethod.getAnnotation(RequestMapping.class).value();
                        String allUrl=((baseUrl+url).trim()).replaceAll("//","/");
                        handlerMapping.put(allUrl,declaredMethod);
                    }
                }
            }
        });
        
		sce.getServletContext().setAttribute("applicationContext",beanFactory);
        sce.getServletContext().setAttribute("handlerMapping",handlerMapping);
    }
    /**
     * 扫描指定的包下面的所有类
     * @param basePackagePath  扫描路径
     */
    public void doScan(String basePackagePath){
        //获取classPath路径在硬盘中的url
        URL url=DispatcherServlet.class.getClassLoader().getResource(basePackagePath);
        //从url中获取文件对象(绝对路径)
        File basePackageFile = new File(url.getFile());
        for (File file : basePackageFile.listFiles()) {
            if(file.isDirectory()){
                doScan(basePackagePath+"/"+file.getName());//递归调用
            }else{
               		allClassNameList.add(basePackagePath.replaceAll("/","\\.")+"."+file.getName().replace(".class",""));
            }
        }
	}
    @Override
    public void contextDestroyed(ServletContextEvent sce) {}
}

/**
 * 1.接收客户端的请求
 * 2.分发请求
 */
public class DispatcherServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map applicationContext = (Map) getServletContext().getAttribute("applicationContext");
        Map handlerMapping = (Map) getServletContext().getAttribute("handlerMapping");
		System.out.println(handlerMapping);
        String[] split = req.getRequestURI().split("/");
        String baseUrl="/"+split[1];
        String actionUrl="/"+split[2];
        String url=baseUrl+actionUrl;

        Method method= (Method) handlerMapping.get(url);
        try {
            method.setAccessible(true);
            //调用具体的处理请求的方法
            method.invoke(applicationContext.get(split[1]+"Controller"),req,resp);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
	}
}

//application.properties文件
scan-package=com.zll.goods
 
//xml文件
<?xml version="1.0" encoding="utf-8" ?>
<beans>
    <bean name="memberController" class="com.zll.goods.controller.MemberController">
        <properties>
            <property name="memberService01" bean="memberService"></property>
            <property name="vipNumber" value="01200519"></property>
        </properties>
    </bean>

    <bean name="goodsController" class="com.zll.goods.controller.GoodsController">
        <properties>
            <property name="goodsService" bean="goodsService"></property>
        </properties>
    </bean>

    <bean name="goodsService" class="com.zll.goods.service.GoodsService">
        <properties>
            <property name="goodsDao" bean="goodsDao"></property>
            <property name="memberDao" bean="memberDao"></property>
        </properties>
    </bean>

    <bean name="memberService" class="com.zll.goods.service.MemberService"></bean>

    <bean name="memberDao" class="com.zll.goods.dao.MemberDao"></bean>
    <bean name="goodsDao" class="com.zll.goods.dao.GoodsDao"></bean>
</beans>
        
//db.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/bigdata06?serverTimezone=Asia/Shanghai
username=root
password=1234
initialSize=5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值