Spring框架的IOC(Inversion of Control,控制反转)和AOP(Aspect-OrientedProgramming,面向切面编程)功能实践(软件工程综合实践课程第九周作业)

一、要求

(1) 自行设计一个项目,使用Spring框架的IOC和AOP功能完成;
(2) 项目名为“week9_学号”;
(3) 根据要求撰写实验报告;

二、知识总结

Spring 框架介绍

1 .Spring 框架概念

Spring 是一个非常优秀的开源框架,由 Rod Johnson 于 2003 年创建。它是为了解决企业应用开发复杂性而创建的。Spring 框架是 Java 应用中最广的框架,它的成功来源于设计思想,而不是技术本身,即 IoC(Inversion of Control,控制反转)和 AOP(Aspect Oriented Programming,面向切面编程)核心概念。它将 面向接口的编程思想贯穿整个系统应用,解决了项目中各层的 松耦合问题,简化了企业项目的开发。

2. 核心功能之一:IOC(控制反转)

Spring IOC(Inversion of Control,控制反转)像一个容器,Spring 认为一切 Java 资
源都是 Java Bean,容器的目标就是管理这些 Bean 和它们之间的关系。所以,在 Spring IOC
里管理了各种 Bean(资源),它们的创建、事件、行为、资源之间的依赖关系等,都
由 Spring IOC 容器根据配置文件的描述来完成管理任务。因此,使用 Spring 框架就是将
对象的创建、销毁、初始化等一系列生命周期的过程,都交给 Spring 容器来处理

百度百科:JavaBean 是一种 JAVA 语言写成的可重用组件。为写成 JavaBean,类必
须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法,将内部域私有的成员属性,通过 set 和 get 方法获取。其他 Java 类可以通过反射机制发现和操作这些 JavaBean 的属性。

使用 Spring IOC 技术,解决了对象之间的耦合度过高的问题。没有引入 IOC 之前,对象 A 必须主动去创建对象 B,控制权在 A;引入 IOC 容器后,A 和 B 之间失去了直接联系,当 A 需要 B 时,IOC 容器主动创建一个 B 注入到 A 中,A 从主动变成了被动,称为“控制反转”,或“依赖注入”。

3. 核心功能之二:AOP(面向切面编程)

(1)AOP 的基本概念

实际项目开发中, 日志、事务、权限等功能模块是必须要考虑的。这些功能模块往往横向地散布在所有对象层次中(如下图),与对象的核心功能关系并不密切。如果采用传统的 OOP 设计,会导致大量代码的重复,不利于各个模块的重用。
在这里插入图片描述
AOP(Aspect-OrientedProgramming,面向切面编程)是 OOP 的补充和完善,它利用一种称为" 横切"的技术,将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为 切面。所谓“ 切面”,简单说就是将那些与业务无关,却被业务模块所共同调用的功能封装起来,以减少系统的重复代码,降低模块之间的耦合度,增加系统的可维护性

使用“横切”技术,AOP 把软件系统分为两个部分: 核心关注点和横切关注点。业务处理的主要流程核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,它们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志打印、事务(如下图)。
在这里插入图片描述
AOP 的作用在于分离系统中的核心关注点和横切关注点,可以实现在不改变原程序的基础上,为代码增加新的功能。

(2)代理设计模式

AOP 的底层设计思想是 代理设计模式。Proxy 代理模式是 23 种设计模式之一,属于结构型设计模式,其目的就是为某个类(被代理类)提供一个 代理类,以控制对被代理类的访问。因此,这个被代理类本身不做实际的操作,而是通过其他类来得到自己想要的结果,扩展自己的功能,增加额外的功能。

代理类主要负责:为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的等后续处理。所以,当两个类需要通信时,代理设计模式通过 引入第三方代理类,将两个类的关系解耦,使得程序只要了解代理类即可。代理设计模式的 UML类图如下。

在这里插入图片描述
上图表示, 代理模式的构成:

  • 1)一个接口(Subject):接口中的方法是要真正去实现的;
  • 2)被代理类(RealSubject):实现上述接口,这是真正去执行接口中方法的类;
  • 3)代理类(Proxy):实现上述接口,同时封装被代理类对象,帮助被代理类去实
    现方法;

注意 :使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法。代理类会对被代理类中的方法进行封装,扩展其功能。

静态代理

优点:可以将公共功能抽取成代理类,通过代理类可以扩展被代理类的功能,方便代码的复用、维护和功能扩展。

缺点:代理类的一个方法只服务于被代理类的一个方法,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了;同时,如果接口增加一个方法,代理类也需要实现此方法,增加了代码维护的复杂度。

JDK 中提供动态代理机制

JDK 中提供了 动态代理机制,提供了java.lang.reflect.Proxy 类来实现动态代理,通过它的 newProxyInstance()方法,可以获得代理实现类。同时,对于代理的接口的实际处理,是一个 java.lang.reflect.InvocationHandler,它提供了一个 invoke()方法,供实现者提供相应的代理逻辑的实现。使用动态代理之后,被代理类中增加新方
法,可以不用更改代码就能自动更新代理类。

(3 )AOP 中常见术语

Spring 的 AOP 功能就使用了 动态代理机制。通过动态代理,可以在指定位置执行对应流程。这样就可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置插入这些功能,实现类面向切面编程,亦即 AOP。

  • Target(目标类):需要被代理的类。例如:ZhifuDaoImpl
  • Joinpoint(连接点):目标类中那些可能被拦截的方法。
    例如:ZhifuDaoImpl 的所有方法
    -PointCut(切入点):已经被==增强(通知)==的连接点。例如:pay()方法;
  • Advice(通知/增强):增强代码,如 log()。根据方法的调用先后顺序分为前置通
    知、后置通知、异常通知、环绕通知等;
  • Weaving(织入):把增强advice应用到目标对象target,来创建新的代理对象proxy的过程;
  • proxy 代理类:通知+切入点(由动态代理自动生成的类)
  • Aspect(切面): 是切入点 PointCut 和通知 Advice 的结合,表达了要处理的问题涉及到的所有相关内容。

4. Spring 框架的主要模块

Spring 框架包含的功能由 20 多个模块组成。这些模块按组可分为核心容器、数据访问/集成、Web、AOP(面向切面编程)、设备、消息和测试等。
在这里插入图片描述
核心模块如下:

  • Spring-core 模块:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。
  • Spring-beans 模块:提供了 BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为 Bean。
  • Spring-context 模块:建立在 Core 和Beans 模块的基础之上,提供一个框架式的对象访问方式,是访问定义和配置的任何对象的媒介。ApplicationContext接口是 Context 模块的焦点。
  • Spring-context-support 模块:支持整合第三方库到 Spring 应用程序上下文,特别是用于高速缓存(EhCache、JCache)和任务调度(CommonJ、Quartz)的支持。
  • Spring-expression 模块:提供了强大的表达式语言去支持运行时查询和操作对象图。这是对 JSP2.1 规范中规定的统一表达式语言(Unified EL)的扩展。该语言支持设置和获取属性值、属性分配、方法调用、访问数组、集合和索引器的内容、逻辑和算术运算、变量命名以及从 Spring 的 IOC 容器中以名称检索对象。它还支持列表投影、选择以及常用的列表聚合。

5. Spring 作用

  • IOC 思想:方便解耦,简化开发,可以将所有对象创建和依赖关系维护,交给 Spring 容器管理;
  • AOP 支持:提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能;
  • 声明式事务的支持:只需要通过配置就可以完成对事务的管理,而无需手动编程;
  • 方便集成各种优秀框架:Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持。Spring 框架可以无缝整合其他的框架:MyBatis、Hibernate、Redis、SpringMVC、SpringDATA 等。

Spring 框架的单例、多例、初始化、销毁等功能

  • 单例和多例
    在这里插入图片描述

  • 初始化和销毁应用
    程序设计时,希望能自动控制类的方法的调用顺序,如对Person类的work()方法来说:希望在执行work()方法时,程序首先会自动执行 getup()方法,然后再执行work()方法,最后自动执行sleep()方法。
    在这里插入图片描述
    在这里插入图片描述

  • 懒加载和非懒加载应用
    默认情况下,spring 容器启动时,会自动创建配置文件中的所有类的实例对象,但实际应用中,有些类是需要调用时才要创建的。因此,可在配置文件中设置“lazy-init”属性告诉 spring 容器,是否以懒加载方式创建对象。

  • 通过有参的构造函数创建对象
    当对象有属性需要在创建时就赋值,可在配置文件中做如下修改。先建立一个局部配置文件:
    在这里插入图片描述
    再将该局部文件引入到主配置文件中。
    在这里插入图片描述

  • Ref 标签:一个类的成员变量为某个类
    在这里插入图片描述

三、项目结构

在这里插入图片描述

四、项目主要功能简介

本项目使用Spring框架的IOC和AOP功能实现了一个计算器项目,该项目可以进行加减乘除操作,并使用AOP模拟实现了在计算开始前检查环境是否适合运算、运算结束后记录运算日志及记录完日志后安全退出的功能。

输入待运算数值及运算符后,运算完成后的值会输出到控制台,本项目还模拟了运算结束后将运算的数值和运算符以及运算结果等信息输出到控制台并存储到数据库的操作。

五、完整参考代码

cn/java/bean包

cn/java/bean/Cal.java

package cn.java.bean;

/**
 * @projectName: week9_
 * @package: cn.java.bean
 * @className: Cal
 * @author: GCT
 * @description: 运算类的父类
 * @date: 2022/10/26 12:06
 * @version: 1.0
 */
public class Cal {
    private String strNumberA;
    private String strNumberB;

    private String operator;
    private String strResult;

//    public String getStrResult() {
//        return strResult;
//    }

    public void setStrResult(String strResult) {
        this.strResult = strResult;
    }

    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public String getStrNumberA() {
        return strNumberA;
    }

    public void setStrNumberA(String strNumberA) {
        this.strNumberA = strNumberA;
    }

    public String getStrNumberB() {
        return strNumberB;
    }

    public void setStrNumberB(String strNumberB) {
        this.strNumberB = strNumberB;
    }

    public String getResult(){
        return "";
    }

    @Override
    public String toString() {
        return "Cal{" +
                "strNumberA='" + strNumberA + '\'' +
                ", strNumberB='" + strNumberB + '\'' +
                ", operator='" + operator + '\'' +
                ", strResult='" + strResult + '\'' +
                '}';
    }
}

cn/java/bean/AddCal.java

package cn.java.bean;

/**
 * @projectName: week9_ 
 * @package: cn.java.bean
 * @className: AddCal
 * @author: GCT
 * @description: 加法子类
 * @date: 2022/10/26 12:07
 * @version: 1.0
 */
public class AddCal extends Cal{
    @Override
    public String getResult() {
        return Double.toString( Double.valueOf(getStrNumberA()) + Double.valueOf(getStrNumberB()));
    }

}

cn/java/bean/MinusCal.java

package cn.java.bean;

/**
 * @projectName: week9_ 
 * @package: cn.java.bean
 * @className: MinusCal
 * @author: GCT
 * @description: 减法子类
 * @date: 2022/10/26 12:08
 * @version: 1.0
 */
public class MinusCal extends Cal{
    @Override
    public String getResult() {
        return Double.toString( Double.valueOf(getStrNumberA()) - Double.valueOf(getStrNumberB()));
    }

}

cn/java/bean/MultiCal.java

package cn.java.bean;

/**
 * @projectName: week9_ 
 * @package: cn.java.bean
 * @className: MultiCal
 * @author: GCT
 * @description: 乘法子类
 * @date: 2022/10/26 12:09
 * @version: 1.0
 */
public class MultiCal extends Cal{
    @Override
    public String getResult() {
        return Double.toString( Double.valueOf(getStrNumberA()) * Double.valueOf(getStrNumberB()));
    }

}

cn/java/bean/DevideCal.java

package cn.java.bean;

/**
 * @projectName: week9_ 
 * @package: cn.java.bean
 * @className: DevideCal
 * @author: GCT
 * @description: 除法子类
 * @date: 2022/10/26 12:10
 * @version: 1.0
 */
public class DevideCal extends Cal{
    @Override
    public String getResult() {
        if (Double.valueOf(getStrNumberB()) != 0){
            return Double.toString( Double.valueOf(getStrNumberA()) / Double.valueOf(getStrNumberB()));
        }
        else {
            return "除数不能为零";
        }

    }
}

cn/java/service包

cn/java/service/impl包

cn/java/service/impl/CalculateServiceImpl.java
package cn.java.service.impl;

import cn.java.bean.Cal;
import cn.java.dao.CalDao;
import cn.java.service.CalculateService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * @projectName: week9_ 
 * @package: cn.java.service.impl
 * @className: CalculateServiceImpl
 * @author: GCT
 * @description: TODO
 * @date: 2022/10/26 12:43
 * @version: 1.0
 */

public class CalculateServiceImpl implements CalculateService {


/**
 * @param strNumberA:
 * @param operator:
 * @param strNumberB:
 * @return void
 * @author 86139
 * @description 计算运算后的值并输出到控制台
 * @date 2022/10/26 19:49
 */
    @Override
    public void Calculate(String strNumberA,String operator,String strNumberB) {


        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        HashMap<String, String> stringStringHashMap = new HashMap<>();

//        配置运算符和运算类ID的映射关系
        stringStringHashMap.put("+","add");
        stringStringHashMap.put("-","minus");
        stringStringHashMap.put("*","multi");
        stringStringHashMap.put("/","devide");

//        通过运算符取到对应的运算类
        Cal cal = (Cal)context.getBean(stringStringHashMap.get(operator));

        cal.setStrNumberA(strNumberA);
        cal.setStrNumberB(strNumberB);
        String result = cal.getResult();

        System.out.println("运算结果为:"+strNumberA+operator+strNumberB+" = "+result);

    }

    /**
     * @param strNumberA:
     * @param operator:
     * @param strNumberB:
     * @return void
     * @author 86139
     * @description 计算运算后的值输出到控制台并模拟将cal对象存储到数据库中
     * @date 2022/10/26 19:50
     */
    @Override
    public void CalculateAndSave(String strNumberA, String operator, String strNumberB) {

        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        HashMap<String, String> stringStringHashMap = new HashMap<>();
        stringStringHashMap.put("+","add");
        stringStringHashMap.put("-","minus");
        stringStringHashMap.put("*","multi");
        stringStringHashMap.put("/","devide");

        Cal cal = (Cal)context.getBean(stringStringHashMap.get(operator));

        CalDao calDaoImpl = (CalDao)context.getBean("CalDaoImpl");

        cal.setOperator(operator);
        cal.setStrNumberA(strNumberA);
        cal.setStrNumberB(strNumberB);
        String result = cal.getResult();
        cal.setStrResult(result);

        System.out.println("运算结果为:"+strNumberA+operator+strNumberB+" = "+result);

//        将cal对象存储到数据库中
        calDaoImpl.addCal(cal);



    }
}

cn/java/service/CalculateService.java

package cn.java.service;

public interface CalculateService {

    public void Calculate(String strNumberA,String operator,String strNumberB);

    public void CalculateAndSave(String strNumberA,String operator,String strNumberB);



}

cn/java/dao包

cn/java/dao/impl包

cn/java/dao/impl/CalDaoImpl.java
package cn.java.dao.impl;

import cn.java.bean.Cal;
import cn.java.dao.CalDao;

/**
 * @projectName: week9_ 
 * @package: cn.java.dao.impl
 * @className: CalDaoImpl
 * @author: GCT
 * @description: 模拟将运算类对象信息存入数据库
 * @date: 2022/10/26 19:53
 * @version: 1.0
 */
public class CalDaoImpl implements CalDao {
    @Override
    public int addCal(Cal cal) {
        System.out.println("该cal对象信息为:"+cal);
        System.out.println("已将cal对象数据存入数据库");
        return 1;
    }
}

cn/java/dao/CalDao.java

package cn.java.dao;

import cn.java.bean.Cal;

/**
 * @projectName: week9_ 
 * @package: cn.java.dao
 * @className: CalDao
 * @author: GCT
 * @description: TODO
 * @date: 2022/10/26 19:44
 * @version: 1.0
 */
public interface CalDao {
    public int addCal(Cal cal);
}

cn/java/aop包

cn/java/aop/CheckBefore.java

package cn.java.aop;

/**
 * @projectName: week9_ 
 * @package: cn.java.service.impl
 * @className: CheckBefore
 * @author: GCT
 * @description: 模拟运算前检查环境
 * @date: 2022/10/26 17:31
 * @version: 1.0
 */
public class CheckBefore {
    public void checkSafe(){
        System.out.println("Before1: 正在检查当前环境是否可以开始运算......");
    }

    public void checkSuc(){
        System.out.println("Before2: 当前环境正常!开始运算....");
    }

}

cn/java/aop/ExitAfter.java

package cn.java.aop;

/**
 * @projectName: week9_ 
 * @package: cn.java.service.impl
 * @className: ExitAfter
 * @author: GCT
 * @description: 模拟运算完、记录完日志后退出
 * @date: 2022/10/26 17:32
 * @version: 1.0
 */
public class ExitAfter {
    public void safeExit(){
        System.out.println("After2(order=1): 已安全退出.....");
    }
}

cn/java/aop/LogAfter.java

package cn.java.aop;

/**
 * @projectName: week9_ 
 * @package: cn.java.service.impl
 * @className: LogServiceImpl
 * @author: GCT
 * @description: 模拟运算完后记录日志
 * @date: 2022/10/26 16:56
 * @version: 1.0
 */
public class LogAfter{
    public void log() {
        System.out.println("After1(order=2): 正在记录运算日志....");

    }
}

src/main/resources文件夹

src/main/resources/application.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <bean id="Cal" class="cn.java.bean.Cal">
    </bean>

    <bean id="add" class="cn.java.bean.AddCal" parent="Cal">
    </bean>

    <bean id="minus" class="cn.java.bean.MinusCal" parent="Cal">
    </bean>

    <bean id="multi" class="cn.java.bean.MultiCal" parent="Cal">
    </bean>

    <bean id="devide" class="cn.java.bean.DevideCal" parent="Cal">
    </bean>

    <bean id="CalDaoImpl" class="cn.java.dao.impl.CalDaoImpl">
    </bean>

    <!--   引入局部配置文件  -->
    <import resource="aop.xml"/>



</beans>

src/main/resources/aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <!-- 配置目标类,运算bean -->
    <bean id="calServiceImpl" class="cn.java.service.impl.CalculateServiceImpl" >
    </bean>

    <!--    AOP实验-->
    <!-- 配置切面类,检查bean ,第一个切面-->
    <bean id="CheckBefore" class="cn.java.aop.CheckBefore"></bean>
    <!-- 配置切面类,日志bean ,第二个切面-->
    <bean id="LogAfter" class="cn.java.aop.LogAfter"></bean>
    <!-- 配置切面类,退出bean ,第三个切面-->
    <bean id="ExitAfter" class="cn.java.aop.ExitAfter"></bean>

    <!--    <aop:config></aop:config>-->

    <!--2. 配置aop,开始将目标方法和各切面中的通知方法,进行织入-->
    <aop:config>
        <!--  配置连接点(切入点)
          expression="" 哪些方法满足织入的要求
          execution(* "cn.java.service.impl.CalculateServiceImpl.* (..)":
                        表示该类中的所有方法(不管是公有的,还是私有的)都是切入点
            第一个"*"表示任意类型的返回值,
           *(..)表示带任意参数的方法和不带参数的方法
        -->
<!--        CalculateServiceImpl.* (..)  中间漏了个点报错半天找不到...-->
        <aop:pointcut expression="execution (* cn.java.service.impl.CalculateServiceImpl.* (..))" id="calPoint"/>

        <!-- 配置各切面,不要哪个切面时,注释掉即可 -->

        <!--  配置检测检查环境切面 1. SafeCheck,及通知
           注释:
           ref="CheckBefore"表示<bean id="CheckBefore" class="cn.java.aop.CheckBefore"></bean>
           aop:before: 代表前置通知
           method: 表示CheckBefore类中的通知方法名
           pointcut-ref:切入点的id
         -->
        <aop:aspect ref="CheckBefore" >
            <aop:before method="checkSafe" pointcut-ref="calPoint"/>
            <aop:before method="checkSuc" pointcut-ref="calPoint"/>

        </aop:aspect>

        <!-- 配置日志切面 2:LogAfter,及通知
            oop:after:表示后置通知
            order="2":表示执行的顺序,数字越大越先执行
         -->
        <aop:aspect ref="LogAfter" order="2">
            <aop:after method="log" pointcut-ref="calPoint"/>
        </aop:aspect>

        <!--  配置退出切面 3:ExitAfter,及通知 -->
        <aop:aspect ref="ExitAfter" order="1">
            <aop:after method="safeExit" pointcut-ref="calPoint"/>
        </aop:aspect>
    </aop:config>
</beans>

src/main/resources/log4j.properties


# log4J日志框架的配置文件 文件名字不能改
# 第一句:控制日志的输出级别及往哪里输出信息
# 日志的输出级别:fatal>error>warn>info>debug
# 日志输出在控制台:Console

log4j.rootLogger=DEBUG, CONSOLE

#也可以如下设置,提高总的输出级别,但是降低某一个包或类或方法的级别,这样可以减少输出日志信息
#log4j.rootLogger=ERROR,CONSOLE
#log4j.logger.cn.java.dao.impl=DEBUG
#负责输出日志的类,格式
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender  
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout  
log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n 



src/test/java包

src/test/java/test1.java

import cn.java.service.CalculateService;
import cn.java.service.impl.CalculateServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @projectName: week9_ 
 * @package: PACKAGE_NAME
 * @className: test1
 * @author: GCT
 * @description: TODO
 * @date: 2022/10/26 16:27
 * @version: 1.0
 */
public class test1 {

//    单元测试中最好不要用到Scanner(System.in)进行控制台输入
    @Test
    public void testCalServiceImpl(){
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

        CalculateService calServiceImpl = (CalculateService) context.getBean("calServiceImpl");

        System.out.println("============Calculate方法测试===============================");
        calServiceImpl.Calculate("66","+","123");
        System.out.println("================================================");
        calServiceImpl.Calculate("77","-","33");
        System.out.println("================================================");
        calServiceImpl.Calculate("88","*","20");
        System.out.println("================================================");
        calServiceImpl.Calculate("88","/","2");
        System.out.println("================================================");
        calServiceImpl.Calculate("88","/","0");

        System.out.println("============CalculateAndSave方法测试========================");
        calServiceImpl.CalculateAndSave("34","*","2");
        System.out.println("================================================");
        calServiceImpl.CalculateAndSave("34","/","2");
        System.out.println("================================================");
        calServiceImpl.CalculateAndSave("34","/","0");
        System.out.println("================================================");
        calServiceImpl.CalculateAndSave("34","+","2");
        System.out.println("================================================");
        calServiceImpl.CalculateAndSave("34","-","2");

    }


}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>week9_20201003016</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- JUNIT4 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!--导入Spring aop所需的JAR包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

    </dependencies>


    <build>
        <!--编译的时候同时也把包下面的xml同时编译进去-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

        <plugins>
            <!-- 指定jdk版本 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

六、运行结果

Calculate方法测试:

在这里插入图片描述
在这里插入图片描述

CalculateAndSave方法测试:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GCTTTTTT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值