在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>
最终的结果如下: