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>
复制代码


最终的结果如下:


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

目录
相关文章
|
XML NoSQL Java
《Spring Data官方文档》5.3. Connecting to Cassandra with Spring至5.5. Introduction to CassandraTemplate
5.3. 连接到Spring Cassandra 5.3.1. 外部化连接属性 你需要连接到Cassandra来创建配置文件信息。接触点是键空间的所必需的最小字段,但是为了清楚起见,最好能添加端口。
2239 0
|
2月前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
47 0
|
3月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
49 0
|
2月前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
122 0
|
1月前
|
存储 JSON Java
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
30 2
|
2月前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
|
23天前
|
前端开发 Java 应用服务中间件
Springboot对MVC、tomcat扩展配置
Springboot对MVC、tomcat扩展配置
|
15天前
|
安全 Java 应用服务中间件
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
28 0
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
|
17天前
|
XML Java C++
【Spring系列】Sping VS Sping Boot区别与联系
【4月更文挑战第2天】Spring系列第一课:Spring Boot 能力介绍及简单实践
【Spring系列】Sping VS Sping Boot区别与联系
|
24天前
|
缓存 前端开发 Java
SpringBoot启动后加载初始化数据
SpringBoot启动后加载初始化数据