Springboot之---强大的Servlet(七)

简介: 如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。

一方库、二方库、三方库说明

有些二方库为apache所需类库,当然定义也尽相同,以统一标准为准吧~就像嵌入式这个单词,
如果学习的时候根据服务的命名,猜测其作用,然后再去证实的话,可能我早就认识这个单词了

一方库:本工程中的各模块的相互依赖
二方库:公司内部的依赖库,一般指公司内部的其他项目发布的jar包
三方库:公司之外的开源库, 比如apache、ibm、google等发布的依赖
为什么写这句话就是因为javax是指扩展我的java,因为原生的二方库是不允许被覆盖的。提到的

private Stream<Wrapper> getLoadOnStartupWrappers(Container[] children) {
        Map<Integer, List<Wrapper>> grouped = new TreeMap<>();
        for (Container child : children) {
            Wrapper wrapper = (Wrapper) child;
            int order = wrapper.getLoadOnStartup();
            if (order >= 0) {
                grouped.computeIfAbsent(order, ArrayList::new);
                grouped.get(order).add(wrapper);
            }
        }
        return grouped.values().stream().flatMap(List::stream);
    }

再比如这里面的grouped.computeIfAbsent(order, ArrayList::new);其中Absent译为缺席,入参是key=order,以及函数方法,在key!=null的情况下赋值为newAraayList并返回去。
and this flatMap VS map,其他人举的例子很明朗,我就不摘抄了,https://www.cnblogs.com/yucy/p/10260014.html

JDBC中的servlet

数据库三大范式:
1.第一范式(确保每列保持原子性)
2.第二范式(确保表中的每列都和主键相关)
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
1、DML:Data Manipulation Language 操作语句
2、DDL:data define Language、
3、存储过程执行后
4、查询中也是有事务的:select查询后结果集关闭后
事务并发可能的影响:
1、脏读(读取未提交数据)
A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。
就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个时候A事务立即读取了这个脏数据,
但事务B良心发现,又用回滚把数据恢复成原来干净、纯粹的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读。
2、不可重复读(前后多次读取,数据内容不一致)
事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,
比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,
发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读
3、幻读(前后多次读取,数据总量不一致)
事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,
这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读
幻读产生的根本原因是采用的行级锁,所以只针对脏读和重复读有用
流程
Drivermanager-->getconnection--->connection-->createStatement-->ResultSet executeQuery(String sql) throws SQLException;
流程
流程
重载connection方法可实现在各个数据库中切换,基本不需要太多的代码,JDBC中用到的设计模式?----桥接模式
不知道为啥都在强调jdbc的设计模式,所以引用下《重学设计模式--小博哥》中的案例分析
流程
场景
代码实现登陆:
    public class PayController {
        private Logger logger = LoggerFactory.getLogger(PayController.class);

        public boolean doPay(String uId, String tradeId, BigDecimal amount,
                             int channelType, int modeType) {
            // 微信⽀付
            if (1 == channelType) {
                logger.info("模拟微信渠道⽀付划账开始。uId:{} tradeId:{} amount:
                {
                }
                ", uId, tradeId, amount);
                if (1 == modeType) {
                    logger.info("密码⽀付,⻛控校验环境安全");
                } else if (2 == modeType) {
                    logger.info("⼈脸⽀付,⻛控校验脸部识别");
                } else if (3 == modeType) {
                    logger.info("指纹⽀付,⻛控校验指纹信息");

                    上⾯的类提供了⼀个⽀付服务功能,通过提供的必要字段; ⽤户ID 、交易ID 、 ⾦额 、渠道 、模 式 ,来控制⽀付⽅式。
                    以上的 ifelse 应该是最差的⼀种写法,即使写 ifelse 也是可以优化的⽅式去写的。
                    3. 测试验证
                    3.1 编写测试类
                    以上分别测试了两种不同的⽀付类型和⽀付模式;微信⼈脸⽀付、⽀付宝指纹⽀付
                    3.2 测试结果
                }
            }
            // ⽀付宝⽀付
            else if (2 == channelType) {
                logger.info("模拟⽀付宝渠道⽀付划账开始。uId:{} tradeId:{}
                        amount: {
                }
                ", uId, tradeId, amount);
                if (1 == modeType) {
                    logger.info("密码⽀付,⻛控校验环境安全");
                } else if (2 == modeType) {
                    logger.info("⼈脸⽀付,⻛控校验脸部识别");
                } else if (3 == modeType) {
                    logger.info("指纹⽀付,⻛控校验指纹信息");
                }
            }
            return true;
        }
    }

其实面对这种情况一般我是看到大多数是应用策略+模板的,桥接真的很少听

public abstract class Pay {
 protected Logger logger = LoggerFactory.getLogger(Pay.class);
 protected IPayMode payMode;
 public Pay(IPayMode payMode) {
 this.payMode = payMode;
 }
 public abstract String transfer(String uId, String tradeId, BigDecimal
amount);
}

在这个类中定义了⽀付⽅式的需要实现的划账接⼝: transfer ,以及桥接接⼝; IPayMode ,并
在构造函数中⽤户⽅⾃⾏选择⽀付⽅式。
如果没有接触过此类实现,可以᯿点关注 IPayMode payMode ,这部分是桥接的核⼼

public class WxPay extends Pay {
 public WxPay(IPayMode payMode) {
 super(payMode);
 }
 public String transfer(String uId, String tradeId, BigDecimal amount) {
 logger.info("模拟微信渠道⽀付划账开始。uId:{} tradeId:{} amount:{}",
uId, tradeId, amount);
 boolean security = payMode.security(uId);
 logger.info("模拟微信渠道⽀付⻛控校验。uId:{} tradeId:{} security:
{}", uId, tradeId, security);
 if (!security) {
 logger.info("模拟微信渠道⽀付划账拦截。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
 return "0001";
 }
 logger.info("模拟微信渠道⽀付划账成功。uId:{} tradeId:{} amount:{}",
uId, tradeId, amount);
 return "0000";
 }
} 

支付宝支付

public class ZfbPay extends Pay {
 public ZfbPay(IPayMode payMode) {
 super(payMode);
 }
 public String transfer(String uId, String tradeId, BigDecimal amount) {
 logger.info("模拟⽀付宝渠道⽀付划账开始。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
 boolean security = payMode.security(uId);
 logger.info("模拟⽀付宝渠道⽀付⻛控校验。uId:{} tradeId:{} security:
{}", uId, tradeId, security);
 if (!security) {
 logger.info("模拟⽀付宝渠道⽀付划账拦截。uId:{} tradeId:{}
amount:{}", uId, tradeId, amount);
 return "0001";
 }
 logger.info("模拟⽀付宝渠道⽀付划账成功。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
 return "0000";
 }
}

流程
桥接模式接口


public interface IPayMode {
 boolean security(String uId);
}

刷脸

public class PayFaceMode implements IPayMode{
 protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
 public boolean security(String uId) {
 logger.info("⼈脸⽀付,⻛控校验脸部识别");
 return true;
 }
}
其他同上

测试类编写

@Test
public void test_pay() {
 System.out.println("\r\n模拟测试场景;微信⽀付、⼈脸⽅式。");
 Pay wxPay = new WxPay(new PayFaceMode());
 wxPay.transfer("weixin_1092033111", "100000109893", new
BigDecimal(100));
 System.out.println("\r\n模拟测试场景;⽀付宝⽀付、指纹⽅式。");
 Pay zfbPay = new ZfbPay(new PayFingerprintMode());
 zfbPay.transfer("jlu19dlxo111","100000109894",new BigDecimal(100));
} 
目录
相关文章
|
1月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
128 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
4月前
|
XML Java 应用服务中间件
springboot定制嵌入式的servlet
SpringBoot允许定制嵌入式Servlet容器,如修改配置或更换默认的Tomcat。配置可通过`application.properties`设置`server.port`和`server.tomcat.*`属性。此外,可创建`EmbeddedServletContainerCustomizer` Bean来自定义容器,例如改变端口。要替换默认的Tomcat,需排除`spring-boot-starter-tomcat`依赖,并引入`spring-boot-starter-jetty`。
|
5月前
|
Java 应用服务中间件 容器
手写SpringBoot(二)之动态切换Servlet容器
我们在切换serlvet容器的时候,会将SpringBoot默认的tomcat jar包给排除掉,换上我们需要的jar包,比如jetty。
38 0
|
Java 应用服务中间件 容器
25 SpringBoot使用外置的Servlet容器
25 SpringBoot使用外置的Servlet容器
52 0
|
6月前
|
Java 应用服务中间件 Maven
框架的优点(SpringBoot VS Servlet)
框架的优点(SpringBoot VS Servlet)
|
6月前
|
前端开发 Java 容器
SpringBoot中注册Servlet、Filter和Listener(代码和注解两种方式)
SpringBoot中注册Servlet、Filter和Listener(代码和注解两种方式)
120 0
|
前端开发 Java 应用服务中间件
24 SpringBoot配置嵌入式Servlet容器
24 SpringBoot配置嵌入式Servlet容器
79 0
24 SpringBoot配置嵌入式Servlet容器
|
Java API Spring
在spring boot中添加servlet filter *Listener
在spring boot中添加servlet filter *Listener
在spring boot中添加servlet filter *Listener
|
消息中间件 负载均衡 Java
Springboot之---强大的Servlet(十 一)
如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。
112 0
|
消息中间件 SQL 缓存
Springboot之---强大的Servlet(十)
如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。
142 0