Spring 各类知识板块完整解析 你有没有学到吐血?!!!

Spring源码深度解析 Spring Boot 体系原理总结 Spring Boot 特点如下: 创建独立的 Spring 应用程序; 嵌入的 Tomcat ,无须部署 WAR 文件; 简化 Maven 配置; 自动配置 Spring; 提供生产就绪型功能,如指标、健康检查和外部配置; 绝对没有代码生成,以及对 XML 没有配置要求 首先搭建一个 maven 工程, pom 如下: 然后建立一个 controller 类 最后再加入启动整个项目的 main 函数 最后启动main函数并在浏览器中输入localhost:8080 第一个 Starter spr 阅读详情

                                              目录
      一,Spring Boot原理

     二,JPA原理
           2.1 事务
           2.2 本地事务
           2.3 分布式事务

      三,mybatis 缓存使用
           3.1 一级缓存
           3.2 二级缓存

Spring Boot原理

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。其特点如下:

1.创建独立的Spring应用程序
2.嵌入的Tomcat,无需部署WAR文件
3.简化Maven配置
4.自动配置Spring
5.提供生产就绪型功能,如指标,健康检查和外部配置
6.绝对没有代码生成和对XML没有要求配置 [1]

JPA原理

1.事务

事务是计算机应用中不可或缺的组件模型,它保证了用户操作的原子性 ( Atomicity )、一致性 ( Consistency )、隔离性 ( Isolation ) 和持久性 ( Durabilily )。

2.本地事务

紧密依赖于底层资源管理器(例如数据库连接 ),事务处理局限在当前事务资源内。此种事务处理方式不存在对应用服务器的依赖,因而部署灵活却无法支持多数据源的分布式事务。在数据库连接中使用本地事务示例如下:

public void transferAccount() {  
                        Connection conn = null;  
                        Statement stmt = null;  
                        try{ 
                                    conn = getDataSource().getConnection(); 
 // 将自动提交设置为 false,若设置为 true 则数据库将会把每一次数据更新认定为一个事务并自动提交                
                                        conn.setAutoCommit(false); 
                                        stmt = conn.createStatement();  
                                        // 将 A 账户中的金额减少 500
                          stmt.execute("update t_account set amount = amount - 500 where account_id = 'A'"); 
                                    // 将 B 账户中的金额增加 500 
                          stmt.execute("update t_account set amount = amount + 500 where account_id = 'B'"); 
                                        // 提交事务 
                            conn.commit();  
                       // 事务提交:转账的两步操作同时成功  
                         } catch(SQLException sqle){ 
                                                   // 发生异常,回滚在本事务中的操做  
                                                    conn.rollback(); 
                                                  // 事务回滚:转账的两步操作完全撤销 
                                                   stmt.close();  
                                                    conn.close();  
                         } 
            } 

3. 分布式事务

Java 事务编程接口(JTA:Java Transaction API)和 Java 事务服务 (JTS;Java Transaction Service) 为 J2EE 平台提供了分布式事务服务。分布式事务(Distributed Transaction)包括事务管理器(Transaction Manager)和一个或多个支持 XA 协议的资源管理器 ( Resource Manager )。我们可以将资源管理器看做任意类型的持久化数据存储;事务管理器承担着所有事务参与单元的协调与控制。

public void transferAccount() {  
                       UserTransaction userTx = null; 
                       Connection connA = null; Statement stmtA = null; 
                       Connection connB = null; Statement stmtB = null;
 try{
         // 获得 Transaction 管理对象 
         userTx = (UserTransaction)getContext().lookup("java:comp/UserTransaction");
         connA = getDataSourceA().getConnection();// 从数据库 A 中取得数据库连接 
          connB = getDataSourceB().getConnection();// 从数据库 B 中取得数据库连接 
           userTx.begin(); // 启动事务  
                stmtA = connA.createStatement();// 将 A 账户中的金额减少 500 
stmtA.execute("update t_account set amount = amount - 500 where account_id = 'A'"); 
                                    // 将 B 账户中的金额增加 500  
                                    stmtB = connB.createStatement(); 
stmtB.execute("update t_account set amount = amount + 500 where account_id = 'B'");                             
                                    userTx.commit();// 提交事务 
             // 事务提交:转账的两步操作同时成功(数据库 A 和数据库 B 中的数据被同时更新) 
  } catch(SQLException sqle){ 
               // 发生异常,回滚在本事务中的操纵 
                  userTx.rollback();// 事务回滚:数据库 A 和数据库 B 中的数据更新被同时撤销 
               } catch(Exception ne){ }
 } 

4.两阶段提交

两阶段提交主要保证了分布式事务的原子性:即所有结点要么全做要么全不做,所谓的两个阶段是指:第一阶段:准备阶段;第二阶段:提交阶段。
在这里插入图片描述
准备阶段

事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志,但不提交,到达一种“万事俱备,只欠东风”的状态。

提交阶段:

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

将提交分成两阶段进行的目的很明确,就是尽可能晚地提交事务,让事务在提交前尽可能地完成所有能完成的工作。

mybatis 缓存使用

缓存的重要性是不言而喻的。 使用缓存, 我们可以避免频繁的与数据库进行交互, 尤其是在查询越多、缓存命中率越高的情况下, 使用缓存对性能的提高更明显。

Mybatis中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。二级缓存是指可以跨SqlSession的缓存。是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的。

1.一级缓存

同一个 SqlSession 对象, 在参数和 SQL 完全一样的情况先, 只执行一次 SQL 语句(如果缓存没有过期)

也就是只有在参数和 SQL 完全一样的情况下, 才会有这种情况。

1.1 同一个 SqlSession

@Test
public void oneSqlSession() {
    SqlSession sqlSession = null;
    try {
        sqlSession = sqlSessionFactory.openSession();

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 执行第一次查询
        List<Student> students = studentMapper.selectAll();
        for (int i = 0; i < students.size(); i++) {
            System.out.println(students.get(i));
        }
        System.out.println("=============开始同一个 Sqlsession 的第二次查询============");
        // 同一个 sqlSession 进行第二次查询
        List<Student> stus = studentMapper.selectAll();
        Assert.assertEquals(students, stus);
        for (int i = 0; i < stus.size(); i++) {
            System.out.println("stus:" + stus.get(i));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

在以上的代码中, 进行了两次查询, 使用相同的 SqlSession, 结果如下
在这里插入图片描述
在日志和输出中:

第一次查询发送了 SQL 语句, 后返回了结果;

第二次查询没有发送 SQL 语句, 直接从内存中获取了结果。

而且两次结果输入一致, 同时断言两个对象相同也通过。

1. 2不同的 SqlSession

@Test
public void differSqlSession() {
    SqlSession sqlSession = null;
    SqlSession sqlSession2 = null;
    try {
        sqlSession = sqlSessionFactory.openSession();

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 执行第一次查询
        List<Student> students = studentMapper.selectAll();
        for (int i = 0; i < students.size(); i++) {
            System.out.println(students.get(i));
        }
        System.out.println("=============开始不同 Sqlsession 的第二次查询============");
        // 从新创建一个 sqlSession2 进行第二次查询
        sqlSession2 = sqlSessionFactory.openSession();
        StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);
        List<Student> stus = studentMapper2.selectAll();
        // 不相等
        Assert.assertNotEquals(students, stus);
        for (int i = 0; i < stus.size(); i++) {
            System.out.println("stus:" + stus.get(i));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
        if (sqlSession2 != null) {
            sqlSession2.close();
        }
    }
}

在代码中, 分别使用 sqlSession 和 sqlSession2 进行了相同的查询。

其结果如下
在这里插入图片描述
从日志中可以看到两次查询都分别从数据库中取出了数据。 虽然结果相同, 但两个是不同的对象。

1.3 刷新缓存

**

刷新缓存是清空这个 SqlSession 的所有缓存, 不单单是某个键。

@Test
public void sameSqlSessionNoCache() {
    SqlSession sqlSession = null;
    try {
        sqlSession = sqlSessionFactory.openSession();

        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 执行第一次查询
        Student student = studentMapper.selectByPrimaryKey(1);
        System.out.println("=============开始同一个 Sqlsession 的第二次查询============");
        // 同一个 sqlSession 进行第二次查询
        Student stu = studentMapper.selectByPrimaryKey(1);
        Assert.assertEquals(student, stu);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

如果是以上, 没什么不同, 结果还是第二个不发 SQL 语句。

在此, 做一些修改, 在 StudentMapper.xml 中, 添加

flushCache=“true”

修改后的配置文件如下:

<select id="selectByPrimaryKey" flushCache="true" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from student
    where student_id=#{id, jdbcType=INTEGER}
</select>

结果如下:
在这里插入图片描述
第一次, 第二次都发送了 SQL 语句, 同时, 断言两个对象相同出错。

1.4 总结

在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;

不同的 SqlSession 之间的缓存是相互隔离的;

用一个 SqlSession, 可以通过配置使得在查询前清空缓存;

任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

2 .二级缓存

二级缓存存在于 SqlSessionFactory 生命周期中。

2.1 配置二级缓存

2.1.1 全局开关

在 mybatis 中, 二级缓存有全局开关和分开关, 全局开关, 在 mybatis-config.xml 中如下配置:

<settings>
  <!--全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存。 -->
  <setting name="cacheEnabled" value="true"/>
</settings>

默认是为 true, 即默认开启总开关。

2.1.2 分开关

分开关就是说在 *Mapper.xml 中开启或关闭二级缓存, 默认是不开启的。

2.1.3 entity 实现序列化接口

public class Student implements Serializable {

    private static final long serialVersionUID = -4852658907724408209L;
    
    ...
    
}

2.2 使用二级缓存

@Test
public void secendLevelCacheTest() {

    // 获取 SqlSession 对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //  获取 Mapper 对象
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    // 使用 Mapper 接口的对应方法,查询 id=2 的对象
    Student student = studentMapper.selectByPrimaryKey(2);
    // 更新对象的名称
    student.setName("奶茶");
    // 再次使用相同的 SqlSession 查询id=2 的对象
    Student student1 = studentMapper.selectByPrimaryKey(2);
    Assert.assertEquals("奶茶", student1.getName());
    // 同一个 SqlSession , 此时是一级缓存在作用, 两个对象相同
    Assert.assertEquals(student, student1);

    sqlSession.close();

    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    StudentMapper studentMapper1 = sqlSession1.getMapper(StudentMapper.class);
    Student student2 = studentMapper1.selectByPrimaryKey(2);
    Student student3 = studentMapper1.selectByPrimaryKey(2);
    // 由于我们配置的 readOnly="true", 因此后续同一个 SqlSession 的对象都不一样
    Assert.assertEquals("奶茶", student2.getName());
    Assert.assertNotEquals(student3, student2);

    sqlSession1.close();
}

结果如下:

2018-09-29 23:14:26,889 [main] DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - Created connection 242282810.
2018-09-29 23:14:26,889 [main] DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e70f13a]
2018-09-29 23:14:26,897 [main] DEBUG [com.homejim.mybatis.mapper.StudentMapper.selectByPrimaryKey] - ==>  Preparing: select student_id, name, phone, email, sex, locked, gmt_created, gmt_modified from student where student_id=? 
2018-09-29 23:14:26,999 [main] DEBUG [com.homejim.mybatis.mapper.StudentMapper.selectByPrimaryKey] - ==> Parameters: 2(Integer)
2018-09-29 23:14:27,085 [main] TRACE [com.homejim.mybatis.mapper.StudentMapper.selectByPrimaryKey] - <==    Columns: student_id, name, phone, email, sex, locked, gmt_created, gmt_modified
2018-09-29 23:14:27,085 [main] TRACE [com.homejim.mybatis.mapper.StudentMapper.selectByPrimaryKey] - <==        Row: 2, 小丽, 13821378271, xiaoli@mybatis.cn, 0, 0, 2018-09-04 18:27:42.0, 2018-09-04 18:27:42.0
2018-09-29 23:14:27,093 [main] DEBUG [com.homejim.mybatis.mapper.StudentMapper.selectByPrimaryKey] - <==      Total: 1
2018-09-29 23:14:27,093 [main] DEBUG [com.homejim.mybatis.mapper.StudentMapper] - Cache Hit Ratio [com.homejim.mybatis.mapper.StudentMapper]: 0.0
2018-09-29 23:14:27,108 [main] DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e70f13a]
2018-09-29 23:14:27,116 [main] DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@e70f13a]
2018-09-29 23:14:27,116 [main] DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - Returned connection 242282810 to pool.
2018-09-29 23:14:27,124 [main] DEBUG [com.homejim.mybatis.mapper.StudentMapper] - Cache Hit Ratio [com.homejim.mybatis.mapper.StudentMapper]: 0.3333333333333333
2018-09-29 23:14:27,124 [main] DEBUG [com.homejim.mybatis.mapper.StudentMapper] - Cache Hit Ratio [com.homejim.mybatis.mapper.StudentMapper]: 0.5

以上结果, 分几个过程解释:

第一阶段:

1.在第一个 SqlSession 中, 查询出 student 对象, 此时发送了 SQL 语句;
2.student更改了name 属性;
3.SqlSession 再次查询出 student1 对象, 此时不发送 SQL 语句, 日志中打印了 「Cache Hit Ratio」, 代表二级缓存使用了, 但是没有命中。 因为一级缓存先作用了。
4.由于是一级缓存, 因此, 此时两个对象是相同的。
5.调用了 sqlSession.close(), 此时将数据序列化并保持到二级缓存中。

第二阶段:

6.新创建一个 sqlSession.close() 对象;
7.查询出 student2 对象,直接从二级缓存中拿了数据, 因此没有发送 SQL 语句, 此时查了 3 个对象,但只有一个命中, 因此 命中率 1/3=0.333333;
8.查询出 student3 对象,直接从二级缓存中拿了数据, 因此没有发送 SQL 语句, 此时查了 4 个对象,但只有一个命中, 因此 命中率 2/4=0.5;
9.由于 readOnly=“true”, 因此 student2 和 student3 都是反序列化得到的, 为不同的实例。

2.3 配置详解
查看 dtd 文件, 可以看到如下约束:

<!ELEMENT cache (property*)>
<!ATTLIST cache
type CDATA #IMPLIED
eviction CDATA #IMPLIED
flushInterval CDATA #IMPLIED
size CDATA #IMPLIED
readOnly CDATA #IMPLIED
blocking CDATA #IMPLIED
>

从中可以看出:

cache 中可以出现任意多个 property子元素;
cache 有一些可选的属性 type, eviction, flushInterval, size, readOnly, blocking.

2.3.1 type
type 用于指定缓存的实现类型, 默认是PERPETUAL, 对应的是 mybatis 本身的缓存实现类 org.apache.ibatis.cache.impl.PerpetualCache。

后续如果我们要实现自己的缓存或者使用第三方的缓存, 都需要更改此处。

2.3.2 eviction
eviction 对应的是回收策略, 默认为 LRU。

1.LRU: 最近最少使用, 移除最长时间不被使用的对象。

2.FIFO: 先进先出, 按对象进入缓存的顺序来移除对象。

3.SOFT: 软引用, 移除基于垃圾回收器状态和软引用规则的对象。

4.WEAK: 弱引用, 移除基于垃圾回收器状态和弱引用规则的对象。

2.3.3 flushInterval

flushInterval 对应刷新间隔, 单位毫秒, 默认值不设置, 即没有刷新间隔, 缓存仅仅在刷新语句时刷新。

如果设定了之后, 到了对应时间会过期, 再次查询需要从数据库中取数据。

2.3.4 size
size 对应为引用的数量,即最多的缓存对象数据, 默认为 1024。

2.3.5 readOnly

readOnly 为只读属性, 默认为 false

false: 可读写, 在创建对象时, 会通过反序列化得到缓存对象的拷贝。 因此在速度上会相对慢一点, 但重在安全。

true: 只读, 只读的缓存会给所有调用者返回缓存对象的相同实例。 因此性能很好, 但如果修改了对象, 有可能会导致程序出问题。

2.3.6 blocking

blocking 为阻塞, 默认值为 false。 当指定为 true 时将采用 BlockingCache 进行封装。

使用 BlockingCache 会在查询缓存时锁住对应的 Key,如果缓存命中了则会释放对应的锁,否则会在查询数据库以后再释放锁,这样可以阻止并发情况下多个线程同时查询数据。
在这里插入图片描述
2.4 注意事项

由于在更新时会刷新缓存, 因此需要注意使用场合:查询频率很高, 更新频率很低时使用, 即经常使用 select, 相对较少使用delete, insert, update。

缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。但刷新缓存是刷新整个 namespace 的缓存, 也就是你 update 了一个, 则整个缓存都刷新了。

最好在 「只有单表操作」 的表的 namespace 使用缓存, 而且对该表的操作都在这个 namespace 中。 否则可能会出现数据不一致的情况。

看到这里的朋友点个赞呀,有收获的小伙伴,给个评论呀!!!

2万字系统总结,带你实现 Linux 命令自由?还不赶紧进来学习 2万字系统总结,带你实现 Linux 命令自由? ##前言 Linux 的学习对于一个程序员的重要性是不言而喻的。前端开发相比后端开发,接触 Linux 机会相对较少,因此往往容易忽视它。但是学好它却是程序员必备修养之一。 如果本文对你有所帮助,请点个???? 吧。 作者使用的是阿里云服务器 ECS (最便宜的那种) CentOS 7.7 64位。当然你也可以在自己的电脑安装虚拟机,虚拟机中再去安装 CentOS 系统(这就完全免费了)。至于它的安装教程可以去谷歌搜索下,相关教程非常多。 ##Linux 基 阅读详情

相关推荐

全网最全Spring APO原理 & Spring MVC原理解析

全网最全 Spring APO原理 &Spring MVC原理解析 Spring APO 原理 一,Spring APO概念 “横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect”,即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。 使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的

Java_Pluto的博客 686

SpringBoot 中的那些“开关”

在之前我们就Swagger使用篇,可以了解到根据不同环境更改为不同的配置,让不同的配置逻辑生效的处理办法。其实吧,有没有觉得这东西就像是一个开关,那么SpringBoot 我们可以怎么获取当前环境(获取其他配置相同)从而进行判断做一个开关呢?今天我们就来总结下(以下列举的是常用的几种方式): 方式一:@Value 注解 代码如下(基本容器启动什么地方都可以用): @RestController...

iME_cho的博客 1186

蚁群算法(Ant Colony Optimization,ACO)讲解+代码实现

通常情况下,较优的解对应的路径上的信息素会被加强,而较差解对应的信息素则会减少或蒸发。的化学物质,这种物质会在蚂蚁走过的路径上留下痕迹,后续的蚂蚁会根据这些信息素的浓度来选择路径,从而形成一条从蚁巢到食物源的。在求解TSP蚁群算法中,每只蚂蚁相互独立,用于构造不同的路线,蚂蚁之间通过信息素进行交流,合作求解。的过程,该路段经过的蚂蚁越多,信息素留下的就越多,浓度越高,更多的蚂蚁都会选择这个路段。需要注意的是,蚁群算法是一种。(6)计算每只蚂蚁的总距离:遍历每只蚂蚁的路线,累加经过的城市之间的距离。

m0_73804764的博客 1万+

Spring:组成的七大模块

Spring 由七大模块组成,分别是Spring 核心容器(Spring Core)、应用上下文(Spring Context)、Spring面向切面编程(Spring AOP)、JDBC和DAO模块(Spring DAO)、对象实体映射(Spring ORM)、Web模块(Spring Web)以及MVC模块(SpringWebMVC)。 ...

weixin_39885962的博客 1万+

用python将dycom .dcm格式图像转换为nifti .nii

因为发现目前搜索到的多数中文教程并不能正确将FMRI图像正确转换,例如很多用simpleITk的seriesreader的,所以写了一下自己正确转换的方法。因为FMRI是一个4D数据,有时间轴,所以用seriesreader读写出来的图像把时间轴维度给降维了。当然你用SPM12工具的dycom import也是能正确转换的,但是我还是喜欢python这样的,代码直接简单。

qq_41103479的博客 3609

GBase8a-GDCA认证考试-复习参考题

为提升产品服务水平定期举办GBase产品认证培训,培训更多GBase数据库专业人员,满足用户快速成长的业务需求,建设GBase产品生态。请注意甄别,根据所学知识综合判断,正确率97%(97分)。

weixin_41826637的博客 2369

Spring---七大核心模块

Spring---七大核心模块 核心容器(Spring Core)   核心容器提供Spring框架的基本功能。Spring以bean的方式组织和管理Java应用中的各个组件及其关系。Spring使用BeanFactory来产生和管理Bean,它是工厂模式的实现。BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的...

小白知浅的博客 500

【GameFramework框架内置模块】10、本地化(Localization)

本地化(Localization),也就是我们所说的不同地区的语言适配,比如说中文版“你好”,英文版是“Hello”。GameFramework在本地化方面,不仅支持文本的本地化,还支持任意资源的本地化,比如说游戏中释放烟花的特效也可以做出不同地区的版本,使得中文版烟花里面的“新年好”字样的特效,在英文版里面是“Happy New Year”字样的特效。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2298

spring 有哪些主要模块?

spring 有哪些主要模块? Spring框架的七大模块 1. Spring Core 框架的最基础部分,提供 IoC 容器,对 bean 进行管理。 2.Spring Context 基于 bean,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化、校验和调度等功能。 3.Spring DAO 提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码,还提供了声明性事务管理方法。 4.Spring ORM 提供了常用的“对象/关系”映射APIs的集成层。 其中包括JP.

m0_67401606的博客 365

秃鹰搜索优化算法(BES)详解:从自然捕食到全局优化

秃鹰搜索优化算法(Bald Eagle Search Optimization Algorithm,BES)是由马来西亚学者Alsattar等人于2020年提出的一种新型元启发式优化算法。该算法灵感来源于秃鹰在自然界中高超的捕食行为,特别是其独特的狩猎策略和卓越的视觉搜索能力,模拟了秃鹰捕食鲑鱼等猎物的完整过程。

qq_42212808的博客 1349

YOLOv8目标出入计数部署:讲解C#使用ONNX检测模型进行目标出入计数 可运行完整实例

代码、步骤、讲解完整,可一键运行,效果如下:车辆出入计数人员出入计数。

Limiiiing的博客 79

IntelliJ IDEA 社区版:从安装到插件武装的轻量级开发环境全指南

在 Java 开发工具链中,IDE(集成开发环境)的选择直接影响开发效率与工程体验。IntelliJ IDEA 作为主流 Java IDE 之一,其社区版以开源、免费、轻量著称,基于 Apache 2.0 许可证,由 JetBrains 官方维护,具备完整的 JVM 系语言支持。同时,通过插件体系可有效扩展其功能边界,从而在资源占用与开发能力之间取得平衡。在技术实践中,合理配置 JVM 参数、使用 Maven 镜像源、管理插件列表是提升稳定性和性能的关键。对于学生、个人开发者以及中小型项目,社区版提供了高性

weixin_34055787的博客 317

YOLOv8集成EMA注意力机制YOLOv8完整教程 将EMA注意力机制集成到YOLOv8框架中

YOLOv8教程这篇文章介绍了如何将EMA(高效多尺度注意力)机制集成到YOLOv8目标检测框架中。YOLOv8 EMA注意力机制通过多尺度特征融合和高效计算,能够提升模型对关键特征的关注能力。文章详细解析了EMA的原理和结构设计,包括其核心组件和前向传播过程。此外,提供了完整的实现指南,包括环境准备、项目结构设置、EMA模块代码实现(包含分组处理、空间注意力计算和特征融合等关键步骤)。YOLOv8 YOLOv8 YOLOv8 YOLOv8 YOLOv8

FJN110的博客 925

Spring思维导图,让spring不再难懂(一)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34366546的博客 479

10、边缘智能学习技术解析

本文深入解析了边缘智能学习技术的四大核心方法:联邦学习、DNN拆分、迁移学习和八卦学习。文章从人类大脑的学习机制出发,引出边缘级智能的重要性,并详细阐述各类技术的架构、优势、挑战及适用场景。通过对比分析,展示了不同技术在隐私性、效率、可扩展性等方面的特性,并探讨了未来融合多种技术、软硬件协同优化及应用领域拓展的发展趋势,为边缘智能在物联网与人工智能领域的应用提供了系统性参考。

ppp33的博客 117

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Spring七大模块详解

图解: (自己根据网上的多种版本画的,不正确还望指正) 详解: 核心容器(Spring Code) 概念 是Spring的核心容器,提供了Spring框架的基本功能; 此模块包含的BeanFactory类是Spring的核心类,负责产生和管理Bean,是工程模式的实现; 采用Factory(工厂模式)实现了IOC(控制反转...

Huang1178387848的博客 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Spring全家桶,永远滴神!

说Spring成就了Java,Spring是Java程序员必修课之一,应该没人反对吧?前几年面试最常问的且可以顺利拿到高薪的技能是Spring,随着Spring体系的壮大,除非你在简历上添...

芋艿V 577

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Spring框架的组成及使用spring的好处

Spring框架有七个模块组成,这七个模块或(组件)均可以单独存在,也可以与其他一个或多个模块联合使用,具体分析如下: 1. Spring Core: Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。 2.Spring

yebaihedeyangguang的博客 960

华为 ServiceComb框架

华为 ServiceComb框架 一、ServiceComb 概述 1.背景介绍 ServiceComb 作为Apache 开源组织下的一款微服务框架,其前身为华为云的 微服务引擎 CSE (Cloud Service Engine) 云服务。它意味着国内一款微服务框架在华为和Apache 组织的共同努力下, 随着微服务市场的火爆,一定会让越来越多的开发者所喜欢。 2.首要原则 全球首款进入Apache 的开源微服务项目,中立、开放、标准、无商业Lock-in 开源与商业代码同源,具备零成本平滑迁移商

Java_Pluto的博客 7763

外包离职,历时学习416天,成功上岸百度,分享成长过程~

前言: 没有绝对的天才,只有持续不断的付出。对于我们每一个平凡人来说,改变命运只能依靠努力+幸运,但如果你不够幸运,那就只能拉高努力的占比。 2020年7月,我有幸成为了百度的一名Java后端开发,正如标题所说,我从外包辞职了,10000小时后,走进百度拿下了offer。相信同行都清楚,从外包进大厂有多难,运气之余,也离不开我自己的脚踏实地,所幸每踏出的一步都留下了厚厚的脚印。 下文内容涉及到:面试题(含答案)+学习笔记+电子书籍+学习视频,免费打包分享 百度Java工程师面试经历还原 1.百度4面面试题

Java_Pluto的博客 5411

Kafka技术专题之总体原理和分析介绍(中)

生产者消息对应分区策略 生产者分区投递原则的简单介绍: 1)指明partition的情况下,直接将指明的值直接作为partition值; 2)没有指明partition值但有key的情况下,将key的hash值与topic的partition数进行取余得到partition值; 3)没有partition和key情况下,第一次调用时随机生成一个整数,将这个值与topic可用partition总数取余得到partition值,也就是常说的round-robin算法。 Rebalance Rebalance本

Java_Pluto的博客 2226

Kafka技术专题之总体原理和分析介绍(下)

前提回顾 经过了之前的【Kafka技术专题系列(上)】和【Kafka技术专题系列(中)】的学习,相信您对Kafka的基本原理应该已经有了一个简单的介绍和认识了,接下来需要对总体做个收尾。下篇结束之后,我会对Kafka所有相关的技术板块做细化,做每一个技术板块做深入和扩展。 总体架构 核心优势 kafka被设计成通用的数据流处理平台,日志收集器和消息队列。 高吞吐(日志聚合): 大型数据块的整合(offline 平台的拉取) 低延迟(消息队列) 分区、分布式的实时流处理,从一个流派生新的

Java_Pluto的博客 1320

从外包到腾讯,四年软件路,一路坎坷,把最好的学习结果和经验分享给你们,助你们成功上岸

个人经历: 我是一个地地道道的东北人,有着哈尔滨和大庆两地的混血,出生在大庆,小学、初中、高中都在大庆让胡路区念的,大学考的远点,在大庆的另外一个区,萨尔图区,名字叫做东北石油大学,是一个不出名的双非普通一本院校,我读的专业也不是这个学校好的专业,是一个万金油专业,电子信息工程。 也就是说,我从出生,一直到大学毕业,整整22年的时间,都在那个我最熟悉的城市,大庆。 我不知道大家对这个城市有没有了解,大庆油田、铁人王进喜,而我,就是一个石油子弟,这个称呼大家可能不太熟悉,但是在10年那段时间,这个称呼可以保证

Java_Pluto的博客 1083

美团面试官问我一个字符的String.length()是多少,我说是1,面试官说你回去好好学一下吧

public class testT { public static void main(String [] args){ String A = "hi你是乔戈里"; System.out.println(A.length()); } } 以上结果输出为7。 小萌边说边在IDEA中的win环境下选中String.length()函数,使用ctrl+B快捷键进入到String.length()的定义。 /** * Returns the l.

Java_Pluto的博客 974

Spring Native beta 版发布, 技术融合越来越快,你现在已经掌握了嘛?

一、前言 经过一年半的工作,我很高兴地宣布,Spring Native beta 版发布,并且可在 start.spring.io 中直接使用! 这意味着 Spring 除了支持的常规 Java 虚拟机外部署外,我们还增加了使用 GraalVM 将 Spring 应用程序编译为 Native images 的方式,用来对编译型的 Spring 应用程序提供 bata 版支持。同时也支持 Java 和 Kotlin。 这些 Native Spring 应用程序可以作为独立可执行文件进行部署(无需安装 JVM)

Java_Pluto的博客 522

Spring boot基础教程,带你快速入门

一、SpringBoot简介 1.1原有Spring优缺点分析 1.1.1Spring的优点分析 Spring是Java企业版(JavaEnterpriseEdition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的EnterpriseJavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(PlainOldJavaObject,POJO)实现了EJB的功能。 1.1.2Spring的缺点分析 虽然Spring的组件代码

Java_Pluto的博客 514
上一篇: 全网最全Spring APO原理 & Spring MVC原理解析
下一篇: 阿里面试官对我邪魅一笑:MyBatis,让你无缘阿里
普通网友
博客等级 码龄6年 3807粉丝 69原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值