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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。

ResultSet executeQuery(String sql) throws SQLException;

<dependency>
  <groupId>commons-dbcp</groupId>
  <artifactId>commons-dbcp</artifactId>
</dependency>
org.springframework.transaction.interceptor.TransactionInterceptor
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
    Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
    Method var10001 = invocation.getMethod();
    invocation.getClass();
    return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
}
org.springframework.transaction.TransactionDefinition

其实这里看不出来跟servlet的关联性有多么高,如果实在要说其中的关联性,
还不如将jdbc的整合过程与Mybatis进行比较,或者分析jdbc代码分析封装硬编码的过程,
就连其包下的大部分类名都不与之相关,当然你要说再Servlet与jdbc集成开发的时代,他也是有一定时代和代表性的。

    @CallerSensitive 
    public static Connection getConnection(String url,
        java.util.Properties info) throws SQLException {

        return (getConnection(url, info, Reflection.getCallerClass()));
    }

CallerSensitive是什么鬼?

CallerSensitive老规矩,猜测下Caller=调用,Sensitive=敏感的,那么标识在方法上则是当调用方法时的一些控制。
其中特指Reflection.getCallerClass()能够追踪到调用者的第一人。项目中用是用不到。

学习方法就是学习大佬的学习方法

这里JDBC就先到此为止,我先不得不先记录下我在javacache中遇到的小问题思考。

为什么有ConcurrentHashMap还要加入synchronized

在org.springframework.cache.support.AbstractCacheManager中有一段关于初始化缓存静态配置的代码。

/**
     * Initialize the static configuration of caches.
     * <p>Triggered on startup through {@link #afterPropertiesSet()};
     * can also be called to re-initialize at runtime.
     * @since 4.2.2
     * @see #loadCaches()
     */
public void initializeCaches() {
        Collection<? extends Cache> caches = loadCaches();

        synchronized (this.cacheMap) {
            this.cacheNames = Collections.emptySet();
            this.cacheMap.clear();
            Set<String> cacheNames = new LinkedHashSet<>(caches.size());
            for (Cache cache : caches) {
                String name = cache.getName();
                this.cacheMap.put(name, decorateCache(cache));
                cacheNames.add(name);
            }
            this.cacheNames = Collections.unmodifiableSet(cacheNames);
        }
    }

Triggered:触发
原因:本身put和add的线程安全是由ConcurrentHashMap保证的,但是此时获取的值ConcurrentHashMap并不能保证其他线程对共享变量的值操作时还是原来的值。
怎么说呢,这么看来可能失去了map的本来特性,但其实还是不理解,是不理解这个原因准不准确。

谁提出谁解决:concurrentHashMap只能保证一次操作的原子性,一系列操作的时候就需要加锁了,不能保证第N+1个线程进来的时候获取到的状态是未clear的

Collections.emptySet():如果你想 new 一个空的 List ,而这个 List 以后也不会再添加元素,那么就用 Collections.emptyList() 好了。
new ArrayList() 或者 new LinkedList() 在创建的时候有会有初始大小,多少会占用一内存。
每次使用都new 一个空的list集合,浪费就积少成多,浪费就严重啦,就不好啦。

还有一个

@Override
    @Nullable
    public Cache getCache(String name) {
        Cache cache = this.cacheMap.get(name);
        if (cache != null) {
            return cache;
        }
        else {
            // Fully synchronize now for missing cache creation...
            synchronized (this.cacheMap) {
                cache = this.cacheMap.get(name);
                if (cache == null) {
                    cache = getMissingCache(name);
                    if (cache != null) {
                        cache = decorateCache(cache);
                        this.cacheMap.put(name, cache);
                        updateCacheNames(name);
                    }
                }
                return cache;
            }
        }
    }

其中的getMissingCache方法
@Nullable
    protected Cache getMissingCache(String name) {
        return null;
    }
无论如何都要返回null,那么他还要进行判空意义又何在?

源码注释是这样写的
Return a missing cache with the specified name, or null if such a cache does not exist or could not be created on demand.
Caches may be lazily created at runtime if the native provider supports it. If a lookup by name does not yield any result, an AbstractCacheManager subclass gets a chance to register such a cache at runtime. The returned cache will be automatically added to this cache manager.
返回指定名称的缺失缓存,如果此类缓存不存在或无法按需创建,则返回null。
如果本机提供程序支持,可以在运行时延迟创建缓存,就是其扩展实际是在子类中来复写的,
注意:在spring-data-redis的1.7.2中是没有复写此方法的
在官网中查询https://spring.io/projects/spring-data-redis#support
接入了
 <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>2.1.9.RELEASE</version>
</dependency>
低版本可是没有的呢,具体变化是在2.X前后的区别
protected RedisCache getMissingCache(String name) {
        return allowInFlightCacheCreation ? createRedisCache(name, defaultCacheConfig) : null;
}

第二次见到identityHashMap

实际应用
https://mp.weixin.qq.com/s?__biz=Mzg2ODA3NjA1MA==&mid=2247484317&idx=1&sn=1a5d78d0e5d5e09b1d2ca969a5ae7d23&chksm=ceb09ce0f9c715f6688bf4b38a933730f61df7b432b3ac452924b502fba735e048289c3e0d91&token=950928768&lang=zh_CN#rd

public static void main(String[] args) {
    var var1 = new Integer(1);
    var var2 = new Integer(1);
    System.out.println(var1.equals(var2));

    System.out.println(var1.hashCode());
    System.out.println(var2.hashCode());


    System.out.println(System.identityHashCode(var1));
    System.out.println(System.identityHashCode(var2));
}

控制台输出
true
1
1
1524960486
117009527

org.springframework.cache.Cache对于缓存是应用接口,
Hashmap是否是在并发写的情况下,如果是则不是线程安全的
Consistency(一致性)
getinclude
想要看到源文档时,搜索:JSR107规范即可
推荐文章:https://www.jianshu.com/p/f6a1eae

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
190 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
5月前
|
XML Java 应用服务中间件
springboot定制嵌入式的servlet
SpringBoot允许定制嵌入式Servlet容器,如修改配置或更换默认的Tomcat。配置可通过`application.properties`设置`server.port`和`server.tomcat.*`属性。此外,可创建`EmbeddedServletContainerCustomizer` Bean来自定义容器,例如改变端口。要替换默认的Tomcat,需排除`spring-boot-starter-tomcat`依赖,并引入`spring-boot-starter-jetty`。
|
6月前
|
Java 应用服务中间件 容器
手写SpringBoot(二)之动态切换Servlet容器
我们在切换serlvet容器的时候,会将SpringBoot默认的tomcat jar包给排除掉,换上我们需要的jar包,比如jetty。
47 0
|
Java 应用服务中间件 容器
25 SpringBoot使用外置的Servlet容器
25 SpringBoot使用外置的Servlet容器
56 0
|
7月前
|
Java 应用服务中间件 Maven
框架的优点(SpringBoot VS Servlet)
框架的优点(SpringBoot VS Servlet)
|
7月前
|
前端开发 Java 容器
SpringBoot中注册Servlet、Filter和Listener(代码和注解两种方式)
SpringBoot中注册Servlet、Filter和Listener(代码和注解两种方式)
136 0
|
前端开发 Java 应用服务中间件
24 SpringBoot配置嵌入式Servlet容器
24 SpringBoot配置嵌入式Servlet容器
83 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,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。
117 0
|
消息中间件 SQL 缓存
Springboot之---强大的Servlet(十)
如今回头看下Servlet不仅如此强大,还具有很强烈的参考意义,能在现如今流行的大部分框架中找到它的影子。下面文章不止与探索Servlet,可能在其中穿插其他的关联知识点,旨在能从此次的学习中获取更多的知识点参考资料总结,转化为自己的理解输出,在文中我尽量以截图+复制全限定类名的方式记录,以便感兴趣的再次查找。
146 0