Spring 基于Introduction的引入

简介: Spring 基于Introduction的引入

在spring里面,引入了非常受大众所熟悉的Introduction,这里将会有一个模拟超市过节里面进行商品打折优惠活动时,该如何进行商品的优惠价格控制案例。


由于只是模拟而已,所以数据库方面暂时只是考虑用模拟的数据进行操控。核心部分在于如何引入introduction。


package com.sise.lh.lab05Test.model;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:商品类
 */
public class Goods {
    private int G_id; //商品编号
    private  String G_name;  //商品名称
    private double G_price; //商品单价
    private int G_quantity;  //商品数量
    public int getG_id() {
        return G_id;
    }
    public void setG_id(int g_id) {
        G_id = g_id;
    }
    public String getG_name() {
        return G_name;
    }
    public void setG_name(String g_name) {
        G_name = g_name;
    }
    public double getG_price() {
        return G_price;
    }
    public void setG_price(double g_price) {
        G_price = g_price;
    }
    public int getG_quantity() {
        return G_quantity;
    }
    public void setG_quantity(int g_quantity) {
        G_quantity = g_quantity;
    }
}
复制代码


package com.sise.lh.lab05Test.model;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:用户类
 */
public class User {
    private int uid;
    private String uname;
    private String Level; //用户的级别
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public String getLevel() {
        return Level;
    }
    public void setLevel(String level) {
        Level = level;
    }
}
复制代码


package com.sise.lh.lab05Test.model;
import com.sise.lh.lab05Test.IPay.Amount;
import java.util.List;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:购物凭据类
 */
public class Compute_Price implements Amount {
    private int uid;
    private int goods_id; //购买清单的编号
    private List<Goods> goodsList;
    public double pay_all(){    //计算总价格
        double total=0;
//        在这里添加需要实现的代码
        for (Goods good:goodsList) {
            total+=good.getG_price();
        }
        return total;
    }
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public int getGoods_id() {
        return goods_id;
    }
    public void setGoods_id(int goods_id) {
        this.goods_id = goods_id;
    }
    public List<Goods> getGoodsList() {
        return goodsList;
    }
    public void setGoodsList(List<Goods> goodsList) {
        this.goodsList = goodsList;
    }
}
复制代码


package com.sise.lh.lab05Test.IPay;
public interface Amount{
        double pay_all();  //支付接口
}
复制代码


package com.sise.lh.lab05Test.Dao;
import com.sise.lh.lab05Test.model.Goods;
import com.sise.lh.lab05Test.model.User;
import java.util.HashMap;
import java.util.Map;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:模拟数据库
 */
public class MockDataBase {
    public static Map<Integer,Goods> goodsMap=new HashMap<>();
    public static Map<Integer,User> userMap=new HashMap<>();
    //模拟数据库初始化操作
    static{
        initUsers();
        initGoods();
    }
    public static void initGoods(){
        Goods goods= new Goods();
        goods.setG_id(1002);
        goods.setG_name("冰红茶");
        goods.setG_price(3.5);
        goods.setG_quantity(200);
        Goods goods02= new Goods();
        goods02.setG_id(1003);
        goods02.setG_name("清风纸巾");
        goods02.setG_price(19.5);
        goods02.setG_quantity(200);
        goodsMap.put(10001,goods);
        goodsMap.put(10002,goods02);
    }
    public static void initUsers(){
        User user= new User();
        user.setLevel("vip");
        user.setUname("小明");
        user.setUid(10086);
        User user02= new User();
        user02.setLevel("普通用户");
        user02.setUname("小王");
        user02.setUid(10087);
        userMap.put(user.getUid(),user);
        userMap.put(user02.getUid(),user02);
    }
}
复制代码


以上便是model层的3个bean和一个模拟的支付接口以及一个模拟的数据库

接下来便是服务层的内容:


package com.sise.lh.lab05Test.service;
import com.sise.lh.lab05Test.model.Compute_Price;
import com.sise.lh.lab05Test.model.Goods;
import com.sise.lh.lab05Test.model.User;
import java.util.List;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:客户付款服务
 */
public class PayService {
    //模拟数据库情况
    public Compute_Price Pay(User user,List<Goods> goodsList){
        Compute_Price compute_price=new Compute_Price();
        compute_price.setGoods_id(1001675);
        compute_price.setGoodsList(goodsList);
        compute_price.setUid(user.getUid());
        return compute_price;
    }
    //打印订单内容
    public void printOrderList(Compute_Price compute_price){
        System.out.println("顾客id:"+compute_price.getUid());
        System.out.println("商品票据单号"+compute_price.getGoods_id());
        List<Goods> goodsList=compute_price.getGoodsList();
        for (Goods good:goodsList) {
            System.out.println("商品编号 :"+good.getG_id());
            System.out.println("名称 : "+good.getG_name());
            System.out.println("价格 : "+good.getG_price());
        }
        System.out.println("总价"+compute_price.pay_all());
    }
}
复制代码


使用spring所提供的IntroductionInterception拦截器的时候,需要对其进行相应的新接口的引入:


这个时候,我们可以引入一个打折的接口:


package com.sise.lh.lab05Test.IPay;
import com.sise.lh.lab05Test.model.Compute_Price;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:商品打折
 */
public interface Discount {
    double discount(Compute_Price cp);
}
复制代码


这个时候就到了引入IntroductionInterception拦截器的时候了:


package com.sise.lh.lab05Test.aop;
import com.sise.lh.lab05Test.IPay.Discount;
import com.sise.lh.lab05Test.model.Compute_Price;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;
import java.text.DecimalFormat;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:切面口处
 */
public class OtherIntroduction implements IntroductionInterceptor,Discount {
    //判断调用的方法是否为指定类中的方法
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        if(implementsInterface(methodInvocation.getMethod().getDeclaringClass())){
            return methodInvocation.getMethod().invoke(this,methodInvocation.getArguments());
        }
        return methodInvocation.proceed();
    }
    @Override
    public boolean implementsInterface(Class<?> aClass) {
        return aClass.isAssignableFrom(Discount.class);
    }
    @Override
    public double discount(Compute_Price cp) {
        System.out.println("-----------------------");
        double count=cp.pay_all();
        DecimalFormat df= new DecimalFormat("######0.00");  //精确到小数点后两位数字
        if(count>100){
            System.out.println("优惠活动期间,满100消费即返20的优惠券!");
        }
        if(cp.getUid()==10086){//如果用户是vip用户
            count=count*0.7;
            System.out.println("打折之后,价格是:"+df.format(count));
        }else{ //如果用户不是vip
            count=count*0.9;
            System.out.println("今日优惠,价格是:"+df.format(count));
        }
        return 0;
    }
}
复制代码


最后便是我们的测试类了:


package com.sise.lh.lab05Test.Test;
import com.sise.lh.lab05Test.Dao.MockDataBase;
import com.sise.lh.lab05Test.IPay.Amount;
import com.sise.lh.lab05Test.IPay.Discount;
import com.sise.lh.lab05Test.model.Compute_Price;
import com.sise.lh.lab05Test.model.Goods;
import com.sise.lh.lab05Test.model.User;
import com.sise.lh.lab05Test.service.PayService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * 作者:idea
 * 时间:2017/10/11
 * 使用说明:测试类
 */
public class Test {
    //模拟场景,还未进入打折优惠活动期间
    public void MockNotDisCount(){
        PayService payService=new PayService();
        Map<Integer,Goods> goodsMap= MockDataBase.goodsMap;
        Map<Integer,User> userMap= MockDataBase.userMap;
        //模拟获取两件商品
        Goods goods=goodsMap.get(10001);
        Goods goods02=goodsMap.get(10002);
        //模拟用户
        User user=userMap.get(10086);
        List<Goods> goodsList=new ArrayList<Goods>();
        goodsList.add(goods);
        goodsList.add(goods02);
        //模拟付款
        Compute_Price cp=new Compute_Price();
        cp.setGoodsList(goodsList);
        cp=payService.Pay(user,goodsList);
        //打印凭据
        payService.printOrderList(cp);
    }
    //模拟场景,已经进入打折优惠活动期间
    public void MockDisCount(){
        ApplicationContext context= new ClassPathXmlApplicationContext("Test/aop-introduction.xml");
        Amount amount= (Amount) context.getBean("proxyFactorBean");
        PayService payService=new PayService();
        Map<Integer,Goods> goodsMap= MockDataBase.goodsMap;
        Map<Integer,User> userMap= MockDataBase.userMap;
        //模拟获取两件商品
        Goods goods=goodsMap.get(10001);
        Goods goods02=goodsMap.get(10002);
        //模拟用户
        User user=userMap.get(10086);
        List<Goods> goodsList=new ArrayList<Goods>();
        goodsList.add(goods);
        goodsList.add(goods02);
        //模拟付款
        Compute_Price cp=new Compute_Price();
        cp.setGoodsList(goodsList);
        cp=payService.Pay(user,goodsList);
        //打印凭据
        payService.printOrderList(cp);
        ((Discount)amount).discount(cp);
    }
    public static void main(String[] args) {
        Test test=new Test();
        test.MockNotDisCount();
        System.out.println("--------------------------------------------");
        test.MockDisCount();
    }
}
复制代码


相应的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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--对于bean的初始化申明-->
    <bean id="compute_price" class="com.sise.lh.lab05Test.model.Compute_Price"></bean>
    <bean id="otherIntroduction" class="com.sise.lh.lab05Test.aop.OtherIntroduction"></bean>
    <!--给定相应的实例,并且在初始化的时候进行构造函数里面的注入申明-->
    <bean id="otherAdvice" class="org.springframework.aop.support.DefaultIntroductionAdvisor" >
        <constructor-arg ref="otherIntroduction"></constructor-arg>
        <constructor-arg value="com.sise.lh.lab05Test.IPay.Discount"></constructor-arg>
    </bean>
    <!--代理工厂-->
    <bean id="proxyFactorBean" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces" value="com.sise.lh.lab05Test.IPay.Amount"></property>
        <property name="target" ref="compute_price"></property>
        <property name="interceptorNames">
            <list>
                <value>otherAdvice</value>
            </list>
        </property>
    </bean>
</beans>
复制代码


最终的结果如下:


网络异常,图片无法展示
|

目录
相关文章
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
166 2
|
3月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
12天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
25 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
8天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
20 2
|
4月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
54 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
4月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
119 0
|
1月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
176 2
|
1月前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
138 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......