提交 097df531 编写于 作者: 沉默王二's avatar 沉默王二 💬

面渣逆袭

上级 4ba5c4bc
...@@ -67,17 +67,32 @@ ...@@ -67,17 +67,32 @@
* [蓝桥杯学习路线(建议收藏:+1:)](docs/xuexiluxian/lanqiaobei.md) * [蓝桥杯学习路线(建议收藏:+1:)](docs/xuexiluxian/lanqiaobei.md)
* [算法和数据结构学习路线(建议收藏:+1:)](docs/xuexiluxian/algorithm.md) * [算法和数据结构学习路线(建议收藏:+1:)](docs/xuexiluxian/algorithm.md)
# Java核心 # 面渣逆袭
> [!NOTE] > [!NOTE]
> **Java核心非常重要**!我将其分成了面渣逆袭篇、Java 基础篇(包括基础语法、面向对象、集合框架、异常处理、Java IO 等)、Java 并发篇和 Java 虚拟机篇。 > **面试前必读系列**!包括 Java 基础、Java 集合框架、Java 并发编程、Java 虚拟机、Spring、Redis 等等。
## Java面渣逆袭
- [面渣逆袭(Java 基础篇)必看:+1:](docs/sidebar/sanfene/javase.md) - [面渣逆袭(Java 基础篇)必看:+1:](docs/sidebar/sanfene/javase.md)
- [面渣逆袭(Java 集合框架篇)必看:+1:](docs/sidebar/sanfene/collection.md) - [面渣逆袭(Java 集合框架篇)必看:+1:](docs/sidebar/sanfene/collection.md)
- [面渣逆袭(Java 并发编程篇)必看:+1:](docs/sidebar/sanfene/javathread.md) - [面渣逆袭(Java 并发编程篇)必看:+1:](docs/sidebar/sanfene/javathread.md)
- [面渣逆袭(Java 虚拟机篇)必看:+1:](docs/sidebar/sanfene/jvm.md) - [面渣逆袭(Java 虚拟机篇)必看:+1:](docs/sidebar/sanfene/jvm.md)
- [面渣逆袭(Spring)必看:+1:](docs/sidebar/sanfene/spring.md)
- [面渣逆袭(Redis)必看:+1:](docs/sidebar/sanfene/redis.md)
# 学习建议
> [!NOTE]
> **收集了我所有的知乎高赞帖子**!全方位迷茫解惑。
- [如何阅读《深入理解计算机系统》这本书?](docs/xuexijianyi/read-csapp.md)
- [电子信息工程最好的出路的是什么?](docs/xuexijianyi/electron-information-engineering.md)
# Java核心
> [!NOTE]
> **Java核心非常重要**!我将其分成了Java 基础篇(包括基础语法、面向对象、集合框架、异常处理、Java IO 等)、Java 并发篇和 Java 虚拟机篇。
## Java概述 ## Java概述
...@@ -261,18 +276,19 @@ ...@@ -261,18 +276,19 @@
- [一分钟快速搭建Spring Boot项目](docs/springboot/initializr.md) - [一分钟快速搭建Spring Boot项目](docs/springboot/initializr.md)
- [Spring Boot 整合 MySQL 和 Druid](docs/springboot/mysql-druid.md) - [Spring Boot 整合 MySQL 和 Druid](docs/springboot/mysql-druid.md)
- [Spring Boot为什么不需要额外安装Tomcat?](docs/springboot/tomcat.md) - [Spring Boot 整合 JPA](docs/springboot/jpa.md)
- [Spring Boot 整合 Redis 实现缓存](docs/redis/redis-springboot.md) - [Spring Boot 整合 Redis 实现缓存](docs/redis/redis-springboot.md)
- [Spring Boot 整合 MyBatis-Plus AutoGenerator生成项目骨架代码](docs/kaiyuan/auto-generator.md)
- [Spring Boot 为什么不需要额外安装Tomcat?](docs/springboot/tomcat.md)
## 辅助工具/轮子 ## 辅助工具/轮子
- [Tabby:一款逼格更高的开源终端工具](docs/gongju/tabby.md) - [Tabby:一款逼格更高的开源终端工具](docs/gongju/tabby.md)
- [Warp:一款21世纪人用的终端工具](docs/gongju/warp.md) - [Warp:一款21世纪人用的终端工具](docs/gongju/warp.md)
- [Chocolatey Homebrew:两款惊艳的Shell软件管理器](docs/gongju/Chocolatey-Homebrew.md)
- [chiner:一款开源的数据库设计神器](docs/gongju/chiner.md) - [chiner:一款开源的数据库设计神器](docs/gongju/chiner.md)
- [DBeaver:一款免费的数据库操作工具](docs/gongju/DBeaver.md) - [DBeaver:一款免费的数据库操作工具](docs/gongju/DBeaver.md)
- [knife4j:一款界面更炫酷的API文档生成神器](docs/gongju/knife4j.md) - [knife4j:一款界面更炫酷的API文档生成神器](docs/gongju/knife4j.md)
- [MyBatis-Plus AutoGenerator:一款开发效率更高的代码生成工具](docs/kaiyuan/auto-generator.md)
- [Junit:一个开源的Java单元测试框架](docs/gongju/junit.md) - [Junit:一个开源的Java单元测试框架](docs/gongju/junit.md)
- [fastjson:阿里巴巴开源的JSON解析库](docs/gongju/fastjson.md) - [fastjson:阿里巴巴开源的JSON解析库](docs/gongju/fastjson.md)
- [Gson:Google开源的JSON解析库](docs/gongju/gson.md) - [Gson:Google开源的JSON解析库](docs/gongju/gson.md)
...@@ -339,9 +355,8 @@ ...@@ -339,9 +355,8 @@
## 面试题集合 ## 面试题集合
- [Java:34道精选高频面试题](docs/baguwen/java-basic-34.md) - [Java:34道精选高频面试题](docs/baguwen/java-basic-34.md)
- [Java:HashMap精选面试题](docs/collection/hashmap-interview.md) - [Java:13道HashMap精选面试题](docs/collection/hashmap-interview.md)
- [Redis:12道精选高频面试题)](docs/mianjing/redis12question.md) - [Redis:12道精选高频面试题)](docs/mianjing/redis12question.md)
- [Spring:35道精选面试题](docs/sidebar/sanfene/spring.md)
- [Nginx:40道精选面试题](docs/nginx/40-interview.md) - [Nginx:40道精选面试题](docs/nginx/40-interview.md)
...@@ -403,11 +418,6 @@ ...@@ -403,11 +418,6 @@
- [👏下载→豆瓣9.1分,Pro Git中文版](docs/download/progit.md) - [👏下载→豆瓣9.1分,Pro Git中文版](docs/download/progit.md)
- [👏下载→简历模板](docs/download/jianli.md) - [👏下载→简历模板](docs/download/jianli.md)
### 学习建议
- [如何阅读《深入理解计算机系统》这本书?](docs/xuexijianyi/read-csapp.md)
- [电子信息工程最好的出路的是什么?](docs/xuexijianyi/electron-information-engineering.md)
# 知识库搭建历程 # 知识库搭建历程
......
...@@ -41,6 +41,11 @@ export default defineNavbarConfig([ ...@@ -41,6 +41,11 @@ export default defineNavbarConfig([
icon: "xuexijianyi", icon: "xuexijianyi",
link: "/download/learn-jianyi.md" link: "/download/learn-jianyi.md"
}, },
{
text: "面渣逆袭",
icon: "zhunbei",
link: "/download/nixi.md"
},
{ {
text: "优质文章", text: "优质文章",
icon: "youzhi", icon: "youzhi",
......
import { defineSidebarConfig } from "vuepress-theme-hope"; import { defineSidebarConfig } from "vuepress-theme-hope";
export const sidebarConfig = defineSidebarConfig({ export const sidebarConfig = defineSidebarConfig({
"/zhishixingqiu/": ["java-mianshi-zhinan","readme.md"], "/zhishixingqiu/": ["java-mianshi-zhinan","readme.md"],
"/download/": ["java","pdf","learn-jianyi","nicearticle", "history"], "/download/": ["java","pdf","learn-jianyi","nixi","nicearticle", "history"],
"/xuexiluxian/": [ "/xuexiluxian/": [
{ {
text: "Java", text: "Java",
...@@ -66,32 +66,9 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -66,32 +66,9 @@ export const sidebarConfig = defineSidebarConfig({
text: "二、Java核心", text: "二、Java核心",
collapsable: true, collapsable: true,
children: [ children: [
{
prefix: "sidebar/sanfene/",
text: "2.1 面渣逆袭",
collapsable: true,
children: [
{
text: "Java基础篇",
link: "javase.md",
},
{
text: "Java集合框架篇",
link: "collection.md",
},
{
text: "Java并发编程篇",
link: "javathread.md",
},
{
text: "Java虚拟机篇",
link: "jvm.md",
},
],
},
{ {
prefix: "overview/", prefix: "overview/",
text: "2.2 Java概述", text: "2.1 Java概述",
collapsable: true, collapsable: true,
children: [ children: [
"what-is-java", "what-is-java",
...@@ -102,7 +79,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -102,7 +79,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.3 Java基础语法", text: "2.2 Java基础语法",
collapsable: true, collapsable: true,
children: [ children: [
{ {
...@@ -132,7 +109,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -132,7 +109,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.4 面向对象编程", text: "2.3 面向对象编程",
collapsable: true, collapsable: true,
children: [ children: [
{ {
...@@ -163,6 +140,10 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -163,6 +140,10 @@ export const sidebarConfig = defineSidebarConfig({
text: "接口", text: "接口",
link: "oo/interface", link: "oo/interface",
}, },
{
text: "内部类",
link: "oo/inner-class",
},
{ {
text: "static", text: "static",
link: "oo/static", link: "oo/static",
...@@ -207,7 +188,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -207,7 +188,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.5 字符串&数组", text: "2.4 字符串&数组",
collapsable: true, collapsable: true,
children: [ children: [
...@@ -247,7 +228,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -247,7 +228,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.6 集合框架(容器)", text: "2.5 集合框架(容器)",
collapsable: true, collapsable: true,
children: [ children: [
...@@ -283,7 +264,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -283,7 +264,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.7 IO", text: "2.6 IO",
collapsable: true, collapsable: true,
prefix:"io/", prefix:"io/",
children: [ children: [
...@@ -298,7 +279,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -298,7 +279,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.8 异常处理", text: "2.7 异常处理",
collapsable: true, collapsable: true,
prefix:"exception/", prefix:"exception/",
children: [ children: [
...@@ -321,7 +302,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -321,7 +302,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.9 常用工具类", text: "2.8 常用工具类",
collapsable: true, collapsable: true,
prefix:"common-tool/", prefix:"common-tool/",
children: [ children: [
...@@ -344,7 +325,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -344,7 +325,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.10 Java新特性", text: "2.9 Java新特性",
prefix: "java8/", prefix: "java8/",
collapsable: true, collapsable: true,
children: [ children: [
...@@ -363,7 +344,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -363,7 +344,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.11 Java重要知识点", text: "2.10 Java重要知识点",
prefix:"basic-extra-meal/", prefix:"basic-extra-meal/",
collapsable: true, collapsable: true,
children: [ children: [
...@@ -430,7 +411,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -430,7 +411,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.12 并发编程", text: "2.11 并发编程",
collapsable: true, collapsable: true,
prefix: "thread/", prefix: "thread/",
children: [ children: [
...@@ -546,7 +527,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -546,7 +527,7 @@ export const sidebarConfig = defineSidebarConfig({
], ],
}, },
{ {
text: "2.13 JVM", text: "2.12 JVM",
prefix: "jvm/", prefix: "jvm/",
collapsable: true, collapsable: true,
children: [ children: [
...@@ -677,8 +658,19 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -677,8 +658,19 @@ export const sidebarConfig = defineSidebarConfig({
text: "整合 MySQL和Druid", text: "整合 MySQL和Druid",
link: "springboot/mysql-druid", link: "springboot/mysql-druid",
}, },
{
text: "整合 JPA",
link: "springboot/jpa",
},
{
text: "整合 Redis 实现缓存",
link: "redis/redis-springboot",
},
{
text: "整合 MyBatis-Plus AutoGenerator",
link: "kaiyuan/auto-generator",
},
"springboot/tomcat", "springboot/tomcat",
"redis/redis-springboot",
], ],
}, },
{ {
...@@ -687,6 +679,7 @@ export const sidebarConfig = defineSidebarConfig({ ...@@ -687,6 +679,7 @@ export const sidebarConfig = defineSidebarConfig({
children: [ children: [
"gongju/tabby", "gongju/tabby",
"gongju/warp", "gongju/warp",
"gongju/Chocolatey-Homebrew",
"gongju/chiner", "gongju/chiner",
"gongju/DBeaver", "gongju/DBeaver",
"gongju/knife4j", "gongju/knife4j",
......
...@@ -25,7 +25,7 @@ actions: ...@@ -25,7 +25,7 @@ actions:
- [CS 学习指南👉](/xuexiluxian/) : 一份涵盖 Java、C 语言、C++、Python、Go、前端、操作系统、蓝桥杯、算法和数据结构的全方位 CS 学习路线!清晰且有效! - [CS 学习指南👉](/xuexiluxian/) : 一份涵盖 Java、C 语言、C++、Python、Go、前端、操作系统、蓝桥杯、算法和数据结构的全方位 CS 学习路线!清晰且有效!
- [Java程序员常读书单📚,附下载地址](https://gitee.com/itwanger/JavaBooks) : 助力Java 程序员构建最强知识体系,涵盖Java、设计模式、数据库、数据结构与算法、大数据、架构等等,再也不用辛苦去找下载地址了。 - [Java程序员常读书单📚,附下载地址](https://gitee.com/itwanger/JavaBooks) : 助力Java 程序员构建最强知识体系,涵盖Java、设计模式、数据库、数据结构与算法、大数据、架构等等,再也不用辛苦去找下载地址了。
- [编程喵喵🐱实战项目学习教程](https://github.com/itwanger/codingmore-learning) :codingmore(Spring Boot+Vue 的前后端分离项目,一款值得一试的开源知识库学习网站)的学习教程,需要项目经验的 Java 开发者必备! - [编程喵喵🐱实战项目学习教程](https://github.com/itwanger/codingmore-learning) :codingmore(Spring Boot+Vue 的前后端分离项目,一款值得一试的开源知识库学习网站)的学习教程,需要项目经验的 Java 开发者必备!
- [优质文章精选集📗](download/nicearticle.md) :精选一些 Java 程序员应该读一读的优质文章,帮你少走一些弯路 - [面渣逆袭📗](download/nixi.md) :面试前必刷,硬核理解版八股文,包括 Java 基础、Java 集合框架、Java 并发编程、Java 虚拟机、Spring、Redis 等等,助你拿到心仪 offer
## PDF ## PDF
...@@ -76,6 +76,7 @@ actions: ...@@ -76,6 +76,7 @@ actions:
时间|小伙伴|赞赏金额 时间|小伙伴|赞赏金额
---|---|--- ---|---|---
2022-04-25|*思|5元
2022-04-20|w*n|1元 2022-04-20|w*n|1元
2022-04-12|*生|10元 2022-04-12|*生|10元
2022-03-04|袁*波|99元 2022-03-04|袁*波|99元
......
...@@ -315,6 +315,8 @@ public class Singleton { ...@@ -315,6 +315,8 @@ public class Singleton {
- synchronized 是加锁防止多个线程同时进入该方法创建对象 - synchronized 是加锁防止多个线程同时进入该方法创建对象
- 第二层if(singleton == null) 是防止有多个线程同时等待锁,一个执行完了后面一个又继续执行的情况 - 第二层if(singleton == null) 是防止有多个线程同时等待锁,一个执行完了后面一个又继续执行的情况
[关于双检锁可以参考](https://blog.csdn.net/fly910905/article/details/79286680)
## 22.volatile 有什么作用 ## 22.volatile 有什么作用
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/images/baguwen/basic-34-09.png) ![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/images/baguwen/basic-34-09.png)
......
# 网络日志 # 网络日志
### 2022年05月09日
- [增加面渣逆袭板块](/download/nixi)
- [Spring Boot 整合 MySQL-Druid](/springboot/mysql-druid)
### 2022年04月30日 ### 2022年04月30日
- 批量替换所有图片链接为阿里云的 CDN 链接 - 批量替换所有图片链接为阿里云的 CDN 链接
### 2022年04月29日 ### 2022年04月29日
- [增加内部类](https://tobebetterjavaer.com/oo/inner-class.html) - [增加内部类](/oo/inner-class)
### 2022年04月27日 ### 2022年04月27日
...@@ -22,23 +27,23 @@ ...@@ -22,23 +27,23 @@
### 2022年04月02日 ### 2022年04月02日
- [杨锅锅同学提出错误:浮点多了个long, 整数少了个int](https://tobebetterjavaer.com/sidebar/sanfene/javase.html) - [杨锅锅同学提出错误:浮点多了个long, 整数少了个int](/sidebar/sanfene/javase)
- [增加数据结构与算法的学习路线](https://tobebetterjavaer.com/xuexiluxian/algorithm.html) - [增加数据结构与算法的学习路线](/xuexiluxian/algorithm)
### 2022年03月31日 ### 2022年03月31日
- [增加学习建议板块](http://localhost:8080/home.html#学习建议) - 增加学习建议板块
### 2022年03月29日 ### 2022年03月29日
- [修改学习路线部分的404错误](https://tobebetterjavaer.com/xuexiluxian/) - [修改学习路线部分的404错误](/xuexiluxian/)
- [增加Java整体学习路线](https://tobebetterjavaer.com/xuexiluxian/java/yitiaolong.html) - [增加Java整体学习路线](/xuexiluxian/java/yitiaolong)
- [增加Java虚拟机学习路线](https://tobebetterjavaer.com/xuexiluxian/java/jvm.html) - [增加Java虚拟机学习路线](/xuexiluxian/java/jvm)
### 2022年03月27日 ### 2022年03月27日
- [增加Java并发编程的内容](https://tobebetterjavaer.com/home.html#java并发编程) - [增加Java并发编程的内容](/home#java并发编程)
- [增加Java虚拟机模块的内容](https://tobebetterjavaer.com/home.html#java虚拟机) - [增加Java虚拟机模块的内容](/home#java虚拟机)
### 2022年03月19日 ### 2022年03月19日
......
# 面渣逆袭
>**面试前必读系列**!包括 Java 基础、Java 集合框架、Java 并发编程、Java 虚拟机、Spring、Redis 等等。
- [面渣逆袭(Java 基础篇)必看:+1:](/sidebar/sanfene/javase.md)
- [面渣逆袭(Java 集合框架篇)必看:+1:](/sidebar/sanfene/collection.md)
- [面渣逆袭(Java 并发编程篇)必看:+1:](/sidebar/sanfene/javathread.md)
- [面渣逆袭(Java 虚拟机篇)必看:+1:](/sidebar/sanfene/jvm.md)
- [面渣逆袭(Spring)必看:+1:](/sidebar/sanfene/spring.md)
- [面渣逆袭(Redis)必看:+1:](/sidebar/sanfene/redis.md)
\ No newline at end of file
---
category:
- Java企业级开发
tag:
- 辅助工具/轮子
title: Chocolatey Homebrew:两款惊艳的Shell软件管理器
---
小二是公司新来的实习生,之前面试的过程中对答如流,所以我非常看好他。第一天,我给他了一台新电脑,要他先在本地搭建个 Java 开发环境。
二话不说,他就开始马不停蹄地行动了。真没想到,他竟然是通过命令行的方式安装的 JDK,这远远超出了我对他的预期。
我以为,他会使用图形化的方式来安装 JDK 的,就像这样。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-3d58d8db-e851-4c3d-97a5-66c8bf94d420.png)
还有这样。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-eda6f2a0-a192-4b92-b3cc-46f679ec5bcb.png)
结果他是这样的。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-371831e9-4580-4097-a0bf-d9c460f493fb.png)
卧槽!牛逼高大上啊!
看着他熟练地在命令行里安装 JDK 的样子,我的嘴角开始微微上扬,真不错!这次总算招到了一个靠谱的。
于是我就安排他做一个记录,打算发表在我的小破站《Java 程序员进阶之路》上。从他嘴里了解到,他用的命令行软件管理器叫 chocolatey,这是一个Windows下的命令行软件管理器,可以方便开发者像在Linux下使用yum命令来安装软件,或者像在macOS下使用brew 命令来安装软件,我感觉非常酷炫。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-509ea602-39b0-462e-9b8d-2a55fc31a4c8.png)
以下是他的记录,一起来欣赏下。
### 关于shell
对于一名 Java 后端程序员来说,初学阶段,你可以选择在 IDE 中直接编译运行 Java 代码,但有时候也需要在 Shell 下编译和运行 Java 代码。
>Windows 下自带的 Shell 叫命令提示符,或者 cmd 或者 powershell,macOS 下叫终端 terminal。
- [终端与 Shell 的区别](https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247491253&idx=1&sn=9a46879174f7240267fe5b5205d16d22&scene=21#wechat_redirect)
- [初次体验 macOS 下的 Shell](https://mp.weixin.qq.com/s/oEo8N3nE0wR1zl7qD4nh3w)
但当你需要在生产环境下部署 Java项目或者查看日志的话,就必然会用到 Shell,这个阶段,Shell 的使用频率高到可以用一个成语来形容——朝夕相伴。
一些第三方软件会在原生的 Shell 基础上提供更强大的功能,常见的有 tabby、Warp、xhsell、FinalShell、MobaXterm、Aechoterm、WindTerm、termius、iterm2 等等,有些只能在 Windows 上使用,有些只能在 macOS 上使用,有些支持全平台。还有 ohmyzsh 这种超神的 Shell 美化工具。
这里,我们列举一些 Shell 的基本操作命令(Windows 和 macOS/Linux 有些许差异):
- 切换目录,可以使用 cd 命令切换目录,`cd ..` 返回上级目录。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-d4f0634f-7b5b-4bbd-97eb-74ec1fe059c5.png)
- 目录列表,macos/linux 下可以使用 ls 命令列出目录下所有的文件和子目录(Windows 下使用 dir 命令),使用通配符 `*` 对展示的内容进行过滤,比如 `ls *.java` 列出所有 `.java`后缀的文件,如果想更进一步的话,可以使用 `ls H*.java` 列出所有以 H 开头 `.java` 后缀的文件。
- 新建目录,macOS/Linux 下可以使用 mkdir 命令新建一个目录(比如 `mkdir hello` 可以新建一个 hello 的目录),Windows 下可以使用 md 命令。
- 删除文件,macOS/Linux 下可以使用 `rm` 命令删除文件(比如 `rm hello.java` 删除 hello.java 文件),Windows 下可以使用 del 命令。
- 删除目录,macOS/Linux 下可以使用 `rm -r` 命令删除目录以及它所包含的所有文件(比如说 `rm -r hello` 删除 hello 目录)。Windows 下可以使用 deltree 命令。
- 重复命令,macOS/Linux/Windows 下都可以使用上下箭头来选择以往执行过的命令。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-738501d4-c210-449c-9d6c-56d5d16c623b.png)
- 命令历史,macOS/Linux 下可以使用 `history` 命令查看所有使用过的命令。Windows 可以按下 F7 键。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-e90c8f1f-c46c-47da-be88-0e8a00d85089.png)
- 解压文件,后缀名为“.zip”的文件是一个包含了其他文件的压缩包,macOS/Linux 系统自身已经提供了用于解压的 unzip 命令, Windows 的话需要手动安装。
### 安装JDK
**1)Windows**
推荐先安装 chocolatey。这是一个Windows下的命令行软件管理器,可以方便开发者像在Linux下使用yum命令来安装软件,或者像在macOS下使用brew 命令来安装软件,非常酷炫。
>The biggest challenge is reducing duplication of effort, so users turn to Chocolatey for simplicity
传统的安装方式要么非常耗时,要么非常低效,在命令行安装软件除了简单高效,还能自动帮我们配置环境变量。
>- 官方地址:[https://chocolatey.org/](https://chocolatey.org/)
>- 安装文档:[https://chocolatey.org/install#individual](https://chocolatey.org/install#individual)
安装完成后如下图所示:
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-5fd2b098-5685-49be-b424-f13ac288858d.png)
如果不确定是否安装成功的话,可以通过键入 `choco` 命令来确认。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-a7ea03ef-aa60-47a8-adfc-8b6dde1cf4cc.png)
这里推荐几个非常高效的操作命令:
- choco search xxx,查找 xxx 安装包
- choco info xxx,查看 xxx 安装包信息
- choco install xxx,安装 xxx 软件
- choco upgrade xxx,升级 xxx 软件
- choco uninstall xxx, 卸载 xxx 软件
如何知道 chocolatey 仓库中都有哪些安装包可用呢?
可以通过上面提到的命令行的方式,也可以访问官方仓库进行筛选。
>[https://community.chocolatey.org/packages](https://community.chocolatey.org/packages)
比如说我们来查找 Java。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-a5d6ff0f-f36d-4eb0-a69e-2ba30dd315ea.png)
好,现在可以直接在shell中键入 `choco install jdk8` 来安装 JDK8 了,并且会自动将Java加入到环境变量中,不用再去「我的电脑」「环境变量」中新建 JAVA_HOME 并复制 JDK 安装路径配置 PATH 变量了,是不是非常 nice?
稍等片刻,键入 `java -version` 就可以确认Java是否安装成功了。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-31441e14-b692-4abc-8640-a8b70e08dfae.png)
不得不承认!非常nice!
**2)macOS**
首先推荐安装 homebrew,这是macOS下的命令行软件管理器,用来简化 macOS 上软件的安装过程。homebrew 是开源的,在 GitHub 已收获 32k star。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-0f9c86a0-e4b2-4103-a77e-8771ab8253f5.png)
homebrew 的安装也非常的简单,只需要一行命令即可。
>官方网址:[https://brew.sh/index_zh-cn](https://brew.sh/index_zh-cn)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-b1e8ea1c-2aec-4f79-bdc8-eb3e4fe1a0f0.png)
- 使用 `brew install xxx` 可以安装 macOS 上没有预装的软件
- 使用 `brew install --cask yyy` 可以安装 macOS 其他非开源软件。
这里是 homebrew 常用命令的一个清单,可供参考。
命令| 描述
---|---
brew update| 更新 Homebrew
brew search package| 搜索软件包
brew install package| 安装软件包
brew uninstall package| 卸载软件包
brew upgrade| 升级所有软件包
brew upgrade package| 升级指定软件包
brew list| 列出已安装的软件包列表
brew services command package| 管理 brew 安装软件包
brew services list| 列出 brew 管理运行的服务
brew info package| 查看软件包信息
brew deps package| 列出软件包的依赖关系
brew help| 查看帮助
brew cleanup| 清除过时软件包
brew link package| 创建软件包符号链接
brew unlink package| 取消软件包符号链接
brew doctor| 检查系统是否存在问题
安装完 homebrew 后,建议替换homebrew 的默认源为中科大的,原因就不用我多说了吧?替换方法如下所示:
```
替换brew.git:
cd "$(brew --repo)"
git remote set-url origin https://mirrors.ustc.edu.cn/brew.git
替换homebrew-core.git:
cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
git remote set-url origin https://mirrors.ustc.edu.cn/homebrew-core.git
```
如何知道 homebrew 仓库中都有哪些安装包可用呢?
第一种,通过 `brew search xxx` 命令搜索,比如说我们要搜索 jdk
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-11bdc7b9-5060-4563-9e14-1bc9013882ce.png)
第二种,通过 homebrew 官网搜索,比如说我们要搜索 openjdk。
>官方地址:[https://formulae.brew.sh](https://formulae.brew.sh)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-80b4318e-0491-4ebd-8047-7e4528426921.png)
这里有一份不错的 homebrew 帮助文档,可供参考:
>[https://sspai.com/post/56009](https://sspai.com/post/56009)
OK,我们来安装JDK,只需要简单的一行命令就可以搞定。
`brew install openjdk@8`
对比下载安装包,通过图形化界面的方式安装 JDK,是不是感觉在 Shell 下安装 JDK 更炫酷一些?
关键是还省去了环境变量的配置。
记得还没有走出新手村的时候,就经常被环境变量配置烦不胜烦。那下载这种命令行的方式,要比手动在环境变量中配置要省事一百倍,也更不容易出错。
### 关于编辑器
安装完 Java 之后,你还需要一个编辑器,用来编写 Java 代码。
编辑器多种多样,常见的有集成开发环境(IDE,比如 Intellij IDEA 和 vscode),和简单的文本编辑工具(比如 sublime text)。
我建议这三个工具都要装,日常开发中,我会在这三个编辑器中来回切换。
Intellij IDEA:主要用来编写Java代码,并且最好安装旗舰版,社区版用来学习JavaSE部分是绰绰有余的,但要想拥有更强大的生产力,旗舰版是必须的,因为功能更加强大。
比如说 idea 旗舰版中可以直接通过 Initializr 来创建springboot项目,但社区版就没有此功能。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-d493229a-d62e-42cc-a6f0-7e3c0893a0c5.png)
vscode:更加轻量级的 IDE,在编写Java代码上可以和idea媲美,但要想调试Java代码的话,vscode 和idea的差距还是非常明显的。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-5e913932-58a8-415a-a1aa-30a7e0f2b8aa.png)
我会使用 Intellij IDEA 开发编程喵的后端代码,vscode 来开发编程喵的前端代码。
sublime text:功能更强大的文本编辑器,比记事本这种强大一万倍,也更符合21世纪开发者的外观审美。如果只是简单的修改一下代码格式,或者注释,显然更加方便,因为idea还是比较吃内存的,出差旅行的时候,在笔记本上紧急修改一些代码时,更易用。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/Chocolatey-Homebrew-85aaca81-9e18-4ba9-aaf2-2989abb85fc5.png)
我会配合 GitHub 桌面版来使用 sublime text,编辑 MD 文档的时候会比较舒服。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
...@@ -162,4 +162,4 @@ chiner 还有更多更强大的功能,大家觉得不错的话,可以去尝 ...@@ -162,4 +162,4 @@ chiner 还有更多更强大的功能,大家觉得不错的话,可以去尝
>https://www.yuque.com/chiner/docs/manual >https://www.yuque.com/chiner/docs/manual
<img src="http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png" width="700px"> ![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file \ No newline at end of file
...@@ -57,33 +57,41 @@ headerDepth: 1 ...@@ -57,33 +57,41 @@ headerDepth: 1
## 学习路线 ## 学习路线
>除了 Java 学习路线,还有 C语言、C++、Python、Go 语言、操作系统、前端、蓝桥杯等硬核学习路线,欢迎收藏品鉴! 除了 Java 学习路线,还有 C语言、C++、Python、Go 语言、操作系统、前端、蓝桥杯等硬核学习路线,欢迎收藏品鉴!
* [Java学习路线一条龙版(建议收藏:+1:)](xuexiluxian/java/yitiaolong.md) * [Java学习路线一条龙版(建议收藏:+1:)](xuexiluxian/java/yitiaolong.md)
* [Java并发编程学习路线(建议收藏:+1:)](xuexiluxian/java/thread.md) * [Java并发编程学习路线(建议收藏:+1:)](xuexiluxian/java/thread.md)
* [Java虚拟机学习路线(建议收藏:+1:)](xuexiluxian/java/jvm.md) * [Java虚拟机学习路线(建议收藏:+1:)](xuexiluxian/java/jvm.md)
* [C语言学习路线(建议收藏:+1:)](xuexiluxian/c.md) * [C语言学习路线(建议收藏:+1:)](xuexiluxian/c.md)
* [C++学习路线(建议收藏:+1:)](xuexiluxian/ccc.md) * [C++学习路线(建议收藏:+1:)](xuexiluxian/ccc.md)
* [Python学习路线(建议收藏:+1:)](xuexiluxian/python.md) * [Python学习路线(建议收藏:+1:)](xuexiluxian/python.md)
* [Go语言学习路线(建议收藏:+1:)](xuexiluxian/go.md) * [Go语言学习路线(建议收藏:+1:)](xuexiluxian/go.md)
* [操作系统学习路线(建议收藏:+1:)](xuexiluxian/os.md) * [操作系统学习路线(建议收藏:+1:)](xuexiluxian/os.md)
* [前端学习路线(建议收藏:+1:)](xuexiluxian/qianduan.md) * [前端学习路线(建议收藏:+1:)](xuexiluxian/qianduan.md)
* [蓝桥杯学习路线(建议收藏:+1:)](xuexiluxian/lanqiaobei.md) * [蓝桥杯学习路线(建议收藏:+1:)](xuexiluxian/lanqiaobei.md)
* [算法和数据结构学习路线(建议收藏:+1:)](xuexiluxian/algorithm.md) * [算法和数据结构学习路线(建议收藏:+1:)](xuexiluxian/algorithm.md)
## 面渣逆袭
## Java核心 **面试前必读系列**!包括 Java 基础、Java 集合框架、Java 并发编程、Java 虚拟机、Spring、Redis 等等。
**Java核心非常重要**!我将其分成了面渣逆袭篇、Java 基础篇(包括基础语法、面向对象、集合框架、异常处理、Java IO 等)、Java 并发篇和 Java 虚拟机篇。
### Java面渣逆袭
- [面渣逆袭(Java 基础篇)必看:+1:](sidebar/sanfene/javase.md) - [面渣逆袭(Java 基础篇)必看:+1:](sidebar/sanfene/javase.md)
- [面渣逆袭(Java 集合框架篇)必看:+1:](sidebar/sanfene/collection.md) - [面渣逆袭(Java 集合框架篇)必看:+1:](sidebar/sanfene/collection.md)
- [面渣逆袭(Java 并发编程篇)必看:+1:](sidebar/sanfene/javathread.md) - [面渣逆袭(Java 并发编程篇)必看:+1:](sidebar/sanfene/javathread.md)
- [面渣逆袭(Java 虚拟机篇)必看:+1:](sidebar/sanfene/jvm.md) - [面渣逆袭(Java 虚拟机篇)必看:+1:](sidebar/sanfene/jvm.md)
- [面渣逆袭(Spring)必看:+1:](sidebar/sanfene/spring.md)
- [面渣逆袭(Redis)必看:+1:](sidebar/sanfene/redis.md)
## 学习建议
**收集了我所有的知乎高赞帖子**!全方位迷茫解惑。
- [如何阅读《深入理解计算机系统》这本书?](xuexijianyi/read-csapp.md)
- [电子信息工程最好的出路的是什么?](xuexijianyi/electron-information-engineering.md)
## Java核心
**Java核心非常重要**!我将其分成了Java 基础篇(包括基础语法、面向对象、集合框架、异常处理、Java IO 等)、Java 并发篇和 Java 虚拟机篇。
### Java概述 ### Java概述
...@@ -265,18 +273,20 @@ headerDepth: 1 ...@@ -265,18 +273,20 @@ headerDepth: 1
### SpringBoot ### SpringBoot
- [一分钟快速搭建Spring Boot项目](springboot/initializr.md) - [一分钟快速搭建Spring Boot项目](springboot/initializr.md)
- [Spring Boot为什么不需要额外安装Tomcat?](springboot/tomcat.md) - [Spring Boot 整合 MySQL 和 Druid](springboot/mysql-druid.md)
- [Spring Boot 整合 JPA](springboot/jpa.md)
- [Spring Boot 整合 Redis 实现缓存](redis/redis-springboot.md) - [Spring Boot 整合 Redis 实现缓存](redis/redis-springboot.md)
- [Spring Boot 整合 MyBatis-Plus AutoGenerator生成项目骨架代码](kaiyuan/auto-generator.md)
- [Spring Boot 为什么不需要额外安装Tomcat?](springboot/tomcat.md)
## 辅助工具/轮子
### 辅助工具/轮子
- [Tabby:一款逼格更高的开源终端工具](gongju/tabby.md) - [Tabby:一款逼格更高的开源终端工具](gongju/tabby.md)
- [Warp:一款21世纪人用的终端工具](gongju/warp.md) - [Warp:一款21世纪人用的终端工具](gongju/warp.md)
- [Chocolatey Homebrew:两款惊艳的Shell软件管理器](gongju/Chocolatey-Homebrew.md)
- [chiner:一款开源的数据库设计神器](gongju/chiner.md) - [chiner:一款开源的数据库设计神器](gongju/chiner.md)
- [DBeaver:一款免费的数据库操作工具](gongju/DBeaver.md) - [DBeaver:一款免费的数据库操作工具](gongju/DBeaver.md)
- [knife4j:一款界面更炫酷的API文档生成神器](gongju/knife4j.md) - [knife4j:一款界面更炫酷的API文档生成神器](gongju/knife4j.md)
- [MyBatis-Plus AutoGenerator:一款开发效率更高的代码生成工具](kaiyuan/auto-generator.md)
- [Junit:一个开源的Java单元测试框架](gongju/junit.md) - [Junit:一个开源的Java单元测试框架](gongju/junit.md)
- [fastjson:阿里巴巴开源的JSON解析库](gongju/fastjson.md) - [fastjson:阿里巴巴开源的JSON解析库](gongju/fastjson.md)
- [Gson:Google开源的JSON解析库](gongju/gson.md) - [Gson:Google开源的JSON解析库](gongju/gson.md)
...@@ -341,9 +351,8 @@ headerDepth: 1 ...@@ -341,9 +351,8 @@ headerDepth: 1
### 面试题集合 ### 面试题集合
- [Java:34道精选高频面试题](baguwen/java-basic-34.md) - [Java:34道精选高频面试题](baguwen/java-basic-34.md)
- [Java:HashMap精选面试题](collection/hashmap-interview.md) - [Java:13道HashMap精选面试题](collection/hashmap-interview.md)
- [Redis:12道精选高频面试题)](mianjing/redis12question.md) - [Redis:12道精选高频面试题)](mianjing/redis12question.md)
- [Spring:35道精选面试题](sidebar/sanfene/spring.md)
- [Nginx:40道精选面试题](nginx/40-interview.md) - [Nginx:40道精选面试题](nginx/40-interview.md)
...@@ -403,11 +412,6 @@ headerDepth: 1 ...@@ -403,11 +412,6 @@ headerDepth: 1
- [👏下载→豆瓣9.1分,Pro Git中文版](download/progit.md) - [👏下载→豆瓣9.1分,Pro Git中文版](download/progit.md)
- [👏下载→简历模板](download/jianli.md) - [👏下载→简历模板](download/jianli.md)
### 学习建议
- [如何阅读《深入理解计算机系统》这本书?](xuexijianyi/read-csapp.md)
- [电子信息工程最好的出路的是什么?](xuexijianyi/electron-information-engineering.md)
## 知识库搭建历程 ## 知识库搭建历程
......
--- ---
category: category:
- Java核心 - 面渣逆袭
tag: tag:
- Java - Java
--- ---
......
--- ---
category: category:
- Java核心 - 面渣逆袭
tag: tag:
- Java - Java
--- ---
...@@ -74,7 +74,7 @@ Java 语言既具有编译型语言的特征,也具有解释型语言的特征 ...@@ -74,7 +74,7 @@ Java 语言既具有编译型语言的特征,也具有解释型语言的特征
![编译与解释](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/images/sidebar/sanfene/javase-5.png) ![编译与解释](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/images/sidebar/sanfene/javase-5.png)
<img src="http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png" width="700px"> ![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## 基础语法 ## 基础语法
......
--- ---
category: category:
- Java核心 - 面渣逆袭
tag: tag:
- Java - Java
--- ---
......
--- ---
category: category:
- Java核心 - 面渣逆袭
tag: tag:
- Java - Java
--- ---
...@@ -695,7 +695,7 @@ Parallel Scavenge 的特点是什么? ...@@ -695,7 +695,7 @@ Parallel Scavenge 的特点是什么?
如果一个数据是基本数据类型,不可拆分,它就被称之为标量。把一个 Java 对象拆散,将其用到的成员变量恢复为原始类型来访问,这个过程就称为标量替换。假如逃逸分析能够证明一个对象不会被方法外部访问,并且这个对象可以被拆散,那么可以不创建对象,直接用创建若干个成员变量代替,可以让对象的成员变量在栈上分配和读写。 如果一个数据是基本数据类型,不可拆分,它就被称之为标量。把一个 Java 对象拆散,将其用到的成员变量恢复为原始类型来访问,这个过程就称为标量替换。假如逃逸分析能够证明一个对象不会被方法外部访问,并且这个对象可以被拆散,那么可以不创建对象,直接用创建若干个成员变量代替,可以让对象的成员变量在栈上分配和读写。
<img src="http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png" width="700px"> ![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## 三、JVM 调优 ## 三、JVM 调优
......
此差异已折叠。
--- ---
category: category:
- Java企业级开发 - 面渣逆袭
tag: tag:
- Spring - Spring
--- ---
# Spring:35道精选面试题 # 面渣逆袭(Spring)必看:+1:
> 图文详解 35 道Spring面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳[转载链接](https://mp.weixin.qq.com/s/EQge6DmgIqYITM3mAxkatg),作者:三分恶,戳[原文链接](https://mp.weixin.qq.com/s/Y17S85ntHm_MLTZMJdtjQQ)。 > 图文详解 35 道Spring面试高频题,这次吊打面试官,我觉得稳了(手动 dog)。整理:沉默王二,戳[转载链接](https://mp.weixin.qq.com/s/EQge6DmgIqYITM3mAxkatg),作者:三分恶,戳[原文链接](https://mp.weixin.qq.com/s/Y17S85ntHm_MLTZMJdtjQQ)。
...@@ -127,6 +127,8 @@ Spring 框架中广泛使用了不同类型的设计模式,下面我们来看 ...@@ -127,6 +127,8 @@ Spring 框架中广泛使用了不同类型的设计模式,下面我们来看
6. **适配器模式** :Spring AOP 的增强或通知 (Advice) 使用到了适配器模式、Spring MVC 中也是用到了适配器模式适配 Controller。 6. **适配器模式** :Spring AOP 的增强或通知 (Advice) 使用到了适配器模式、Spring MVC 中也是用到了适配器模式适配 Controller。
7. **策略模式**:Spring 中有一个 Resource 接口,它的不同实现类,会根据不同的策略去访问资源。 7. **策略模式**:Spring 中有一个 Resource 接口,它的不同实现类,会根据不同的策略去访问资源。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## IOC ## IOC
### 5.说一说什么是 IOC?什么是 DI? ### 5.说一说什么是 IOC?什么是 DI?
...@@ -887,56 +889,58 @@ A 实例的初始化过程: ...@@ -887,56 +889,58 @@ A 实例的初始化过程:
- 在 populateBean()方法中一共调用了两次后置处理器,第一次是为了判断是否需要属性填充,如果不需要进行属性填充,那么就会直接进行 return,如果需要进行属性填充,那么方法就会继续向下执行,后面会进行第二次后置处理器的调用,这个时候,就会调用到 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues()方法,在该方法中就会进行@Autowired 注解的解析,然后实现自动装配。 - 在 populateBean()方法中一共调用了两次后置处理器,第一次是为了判断是否需要属性填充,如果不需要进行属性填充,那么就会直接进行 return,如果需要进行属性填充,那么方法就会继续向下执行,后面会进行第二次后置处理器的调用,这个时候,就会调用到 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues()方法,在该方法中就会进行@Autowired 注解的解析,然后实现自动装配。
```java ```java
/** /**
* 属性赋值 * 属性赋值
**/ **/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//………… //…………
if (hasInstAwareBpps) { if (hasInstAwareBpps) {
if (pvs == null) { if (pvs == null) {
pvs = mbd.getPropertyValues(); pvs = mbd.getPropertyValues();
} }
PropertyValues pvsToUse; PropertyValues pvsToUse;
for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) { for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next(); InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName); pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//执行后处理器,填充属性,完成自动装配
//调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法
pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) { if (pvsToUse == null) {
if (filteredPds == null) { return;
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
//执行后处理器,填充属性,完成自动装配
//调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法
pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
} }
} }
} }
//………… }
} //…………
``` }
```
* postProcessorPropertyValues()方法的源码如下,在该方法中,会先调用 findAutowiringMetadata()方法解析出 bean 中带有@Autowired 注解、@Inject 和@Value 注解的属性和方法。然后调用 metadata.inject()方法,进行属性填充。 * postProcessorPropertyValues()方法的源码如下,在该方法中,会先调用 findAutowiringMetadata()方法解析出 bean 中带有@Autowired 注解、@Inject 和@Value 注解的属性和方法。然后调用 metadata.inject()方法,进行属性填充。
```java ```java
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//@Autowired注解、@Inject和@Value注解的属性和方法 //@Autowired注解、@Inject和@Value注解的属性和方法
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs); InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
try { try {
//属性填充 //属性填充
metadata.inject(bean, beanName, pvs); metadata.inject(bean, beanName, pvs);
return pvs; return pvs;
} catch (BeanCreationException var6) { } catch (BeanCreationException var6) {
throw var6; throw var6;
} catch (Throwable var7) { } catch (Throwable var7) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7); throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
}
} }
``` }
```
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## AOP ## AOP
...@@ -1287,6 +1291,9 @@ AspectJ 属于**静态织入**,通过修改代码来实现,在实际运行 ...@@ -1287,6 +1291,9 @@ AspectJ 属于**静态织入**,通过修改代码来实现,在实际运行
![Spring AOP和AspectJ对比](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/images/sidebar/sanfene/spring-d1dbe9d9-c55f-4293-8622-d9759064d613.png) ![Spring AOP和AspectJ对比](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/images/sidebar/sanfene/spring-d1dbe9d9-c55f-4293-8622-d9759064d613.png)
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## 事务 ## 事务
Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring 是无法提供事务功能的。Spring 只提供统一事务管理接口,具体实现都是由各数据库自己实现,数据库事务的提交和回滚是通过数据库自己的事务机制实现。 Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring 是无法提供事务功能的。Spring 只提供统一事务管理接口,具体实现都是由各数据库自己实现,数据库事务的提交和回滚是通过数据库自己的事务机制实现。
...@@ -1443,6 +1450,8 @@ private Integer A() throws Exception { ...@@ -1443,6 +1450,8 @@ private Integer A() throws Exception {
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
``` ```
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## MVC ## MVC
### 28.Spring MVC 的核心组件? ### 28.Spring MVC 的核心组件?
...@@ -1508,6 +1517,8 @@ PS:这是一道全新的八股,毕竟 ModelAndView 这种方式应该没人用 ...@@ -1508,6 +1517,8 @@ PS:这是一道全新的八股,毕竟 ModelAndView 这种方式应该没人用
6. 执行完请求后,返回的 ModealAndView 为 null,ServletServerHttpResponse 里也已经写入了响应,所以不用关心 View 的处理 6. 执行完请求后,返回的 ModealAndView 为 null,ServletServerHttpResponse 里也已经写入了响应,所以不用关心 View 的处理
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
## Spring Boot ## Spring Boot
### 31.介绍一下 SpringBoot,有哪些优点? ### 31.介绍一下 SpringBoot,有哪些优点?
......
---
category:
- Java企业级开发
tag:
- Spring Boot
title: Spring Boot 整合 JPA
---
### 关于 Spring Data JPA
Spring Data 是 Spring 提供的一个操作数据的框架,Spring Data JPA是 Spring Data 下的一个基于 JPA 标准的操作数据的模块。
JPA(Java Persistence API)是 Java 亲妈 Sun 公司提出的一套 Java 持久化规范。所谓规范,就是只定义标准,不提供实现。
JPA 的提出主要是为了整合市面上已有的 ORM 框架,比如说 Hibernate、EclipseLink 等。官方觉得你们搞框架可以,但不要乱搞,得按照我的标准来。
Spring Data JPA 只是一个抽象层,它上接 JPA 下接 ORM 框架,通过基于 JPA 的 Respository 接口极大地减少了 JPA 作为数据访问方案的代码量,简化了持久层开发并且屏蔽了各大 ORM 框架的差异。
总结一下就是:
- JPA 是规范,统一了规范才便于使用。
- Hibernate 是 JPA 的实现,是一套成熟的 ORM 框架。
- Spring Data JPA 是 Spring 提出的,它增加了一个抽象层,用来屏蔽不同 ORM 框架的差异。
### 整合 Spring Data JPA
第一步,在 pom.xml 文件中添加 JPA 的 starter 依赖。
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
```
第二步,在 application.yml 文件中添加数据库连接信息。
```
spring:
datasource:
username: codingmore-mysql
password: dddd
url: jdbc:mysql://xxxx:3306/codingmore-mysql?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
```
第三步,新建实体类 User.java。
```java
@Data
@Entity
@Table(name = "user")
public class User {
@Id
private Integer id;
private Integer age;
private String name;
private String password;
}
```
- `@Data` 注解为 lombok 注解,会自动为该类添加 getter/setter 方法。
- `@Entity``@Table` 注解都是 JDK 1.5 以后引入的元数据注解,遵循 JPA 规范中定义的查询语言 JPQL,类似 SQL 语法,适用于 Java 类。
- `@Entity` 表明该类是一个实体类,默认使用 ORM 规则,即类名为数据库表名,类中的字段名为数据库表中的字段名。
- `@Table` 注解是非必选项,它的优先级高于 `@Entity` 注解,比如说 `@Entity(name="user")``@Table(name="users")` 同时存在的话,对应的表名为 users。
- `@Id` 表名该字段为主键字段,当声明了 @Entity 注解,`@Id` 就必须也得声明。
这里推荐大家在 Intellij IDEA 中安装 JPA Buddy 插件,该插件提供了可视化的代码生成器,可以帮我们简化 JPA 的开发工作。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-dbd461e0-f74b-4914-9f79-37c09bce8db4.png)
安装完 JPA Buddy 插件后,当我们创建好实体类后,会自动打开三个面板:JPA Structure,JPA Palette和JPA Inspector。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-f8e43568-d286-4da6-a61a-c88b50642824.png)
>更多详细介绍:[https://codingdict.com/blog/1406](https://codingdict.com/blog/1406)
在JPA Buddy 插件的帮助下,我们其实可以直接在项目的目录上右键选择通过 JPA 的方式创建实体类。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-ef1d4416-1ac5-4ad8-b305-dafd454cec3b.png)
选择数据表。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-64ad825d-2e53-4315-9fad-3d053d958303.png)
代码如下所示:
```java
@Entity
@Table(name = "user")
public class User {
@Id
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "name", nullable = false, length = 10)
private String name;
@Column(name = "password", nullable = false, length = 10)
private String password;
@Column(name = "age", nullable = false)
private Integer age;
// 省略 getter/setter
}
```
第四步,新建 UserRepository 接口。
在项目路径上右键,选择新建 JPA Repository。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-1114773a-a507-48e9-a1a1-781a89cc517e.png)
生成的代码如下:
```java
public interface UserRepository extends JpaRepository<User, Integer> {
}
```
如果只是简单的对表进行增删改查操作,那么只需要继承 JpaRepository 接口,并传递两个参数(第一个为实体类,第二个为主键类型)即可。
第五步,新建服务接口 UserService 和实现类 UserServiceImpl。
```java
public interface UserService {
User findById(Integer id);
List<User> findAll();
User save(User user);
void delete(Integer id);
}
```
UserService 定义了 4 个方法:
- findById 根据 ID 查询单条记录
- findAll 查询所有
- save 用来保存和更新
- delete 用来删除
```java
@Service
public class UserServiceImpl implements UserService{
@Resource
private UserRepository userRepository;
@Override
public User findById(Integer id) {
return userRepository.getById(id);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public User save(User user) {
return userRepository.save(user);
}
@Override
public void delete(Integer id) {
userRepository.deleteById(id);
}
}
```
- `@Service` 注解用在服务层,和 `@Component` 注解作用类似(通用注解),Spring Boot 会自动扫描该类注解注解的类,并把它们假如到 Spring 容器中。
- `@Resource``@Autowired` 注解都是用来自动装配对象的,可以用在字段上,也可以用在 setter 方法上。@Autowired 是 Spring 提供的注解,@Resource 是 Java 提供的注解,也就是说,如果项目没有使用 Spring 框架而是 JFinal 框架,@Resource 注解也是支持的。另外,@Resource 是 byName 自动装配,@Autowired 是 byType 自动装配,当有两个类型完全一样的对象时,@Autowired 就会出错了。
>苏三写了一篇@Autowired的文章,很不错:[https://www.zhihu.com/question/39356740](https://www.zhihu.com/question/39356740)
当然了,只是简单的增删改查已经不能提起我们学习的兴趣了,必须得来点不一样的,所以我们在 UserService 接口中添加一个分页的接口。
```java
Page<User> findAll(Pageable pageable);
```
实现类:
```java
@Override
public Page<User> findAll(Pageable pageable) {
return userRepository.findAll(pageable);
}
```
- Pageable 是 Spring 提供的一个分页查询接口,查询的时候只需要传入一个 Pageable 接口的实现类,指定第几页(pageNumber)和页面大小(pageSize)即可。
- Page 是 Spring 提供的一个分页返回结果接口。
再增加一个自定义查询接口(按照 name 的模糊查询)吧。
首先是 UserRepository,直接用 JPA Buddy 插件:
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-d4f2619a-85ea-437f-860d-3738669b4582.png)
生成的代码如下:
```java
public interface UserRepository extends JpaRepository<User, Integer> {
List<User> findByNameLikeIgnoreCase(String name);
}
```
然后是 UserService 接口:
```java
List<User> findByNameLikeIgnoreCase(String name);
```
最后是 UserServiceImpl:
```java
@Override
public List<User> findByNameLikeIgnoreCase(String name) {
return userRepository.findByNameLikeIgnoreCase(name);
}
```
### 测试 Spring Data JPA
在测试类中对服务类中的 5 个接口进行测试,顺带在application.yml 中开启 SQL 语句的输出,看看 JPA 自动生成的 SQL 语句到底长什么样子。
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/springboot/jpa-a3d8641a-c701-47bb-ae44-f53eb8e05f65.png)
测试类非常简单哈:
```java
@SpringBootTest
@Slf4j
class CodingmoreJpaApplicationTests {
@Resource
private UserService userService;
@Test
void contextLoads() {
// 查询所有
userService.findAll().stream().forEach(user -> log.info("查询所有{}", user));
// 新增数据
userService.save(new User().setId(2).setAge(12).setName("沉默王三").setPassword("123456"));
userService.save(new User().setId(3).setAge(12).setName("沉默王四").setPassword("123456"));
userService.save(new User().setId(4).setAge(12).setName("沉默王五").setPassword("123456"));
// 分页查询
userService.findAll(PageRequest.of(1,2)).stream().forEach(user -> log.info("分页查询{}", user));
// 模糊查询
log.info("模糊查询{}",userService.findByNameLike("沉默"));
// 删除
userService.delete(1);
}
}
```
从日志当中可以看得出,Spring Data JPA 默认使用的是 Hibernate 框架,这是查询全部:
```
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_, user0_.password as password4_0_ from user user0_
```
这是保存:
```
Hibernate: insert into user (age, name, password, id) values (?, ?, ?, ?)
```
这是更新:
```
Hibernate: update user set age=?, name=?, password=? where id=?
```
这是分页:
```
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_, user0_.password as password4_0_ from user user0_ limit ?, ?
```
这是模糊查询:
```
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_, user0_.password as password4_0_ from user user0_ where user0_.name like ? escape ?
```
不过,这个模糊查询不符合我们的预期,没有前后的 `%`,我们可以选择 Spring Data 提供的 `@Query` 来自定义 SQL 语句。
默认情况下,`@Query` 注解会使用 JPQL 来进行查询。举个例子:
```java
@Query("select u from User u where u.name like concat('%',?1,'%')")
List<User> findByNameLike(String name);
```
`@Query` 注解中的 “User” 为实体类的类名,而非数据库的表名 user,这就是 JPQL 和原生 SQL 的区别。来看原生 SQL 的写法:
```java
@Query(value = "SELECT * FROM user u WHERE u.name like '%'|| ?1 || '%'",
nativeQuery = true)
List<User> findByNameLikeNativeQuery(String name);
```
`@Query` 注解中的 “user” 为数据库表名,另外需要加上参数 nativeQuery,默认值为 false,设为 true 表明开启原生 SQL 查询。注意这次我们用“||”替换了“concat” 方法。
除了使用 `?1``?2` 的形式来动态传递参数,我们还可以使用 `@Param` 注解的形式来传递参数,此时的 SQL 语句中采用 `:param` 形式来接收参数。
```java
@Query("select u from User u where u.name like concat('%',:name,'%')")
List<User> findByNameLikeParam(@Param("name")String name);
```
这是删除:
```
Hibernate: delete from user where id=?
```
### Spring Data JPA 还是 MyBatis
在以往我参与的项目当中,无一例外都选择的是 MyBatis。国内采用 MyBatis 作为 ORM 框架的要比 Spring Data JPA 多得多。
我想原因有这么几个:
1)MyBatis 是针对SQL 的,上手难度比 Spring Data JPA 面向 JPQL 要稍微容易一些。但在 Intellij IDEA 这种集成开发环境的代码提示下,优势并不大。
2)Spring Data JPA 的资料相对少一些,而 MyBatis 的资料可以说非常全面了,遇到问题基本上都能找到解决方案,另外像 MyBatis-Plus 的出现,在一定程度上增强了 MyBatis 的能力。
3)Spring Data JPA 一开始在动态 SQL 能力上不如 MyBatis,但随着 Spring Boot 和 Spring Data JPA 的无缝衔接,Spring Data JPA 的应用会越来越广泛,事实上,国外用 Spring Data JPA 的就比 MyBatis 的多一些。
那在以后的项目当中,我会更加倾向于 Spring Data JPA,原因有这么几点:
1)新项目不用事先设计数据库和表结构,开发过程中可以自动根据实体类生成数据库和表结构,更容易快速迭代。
2)能减少切换数据库带来的改造成本,因为 Spring Data JPA 底层屏蔽了 ORM 框架的差异性;再者不用写原生 SQL 的话,也屏蔽了数据库之间的 SQL 差异性。
3)持久层的代码量更少,维护起来更加简单和方便,更多的时候,只需要维护 entity 和 Respository 接口之间的映射关系就可以了。
### 源码地址:
> - 编程喵:[https://github.com/itwanger/coding-more](https://github.com/itwanger/coding-more)
> - Spring Boot 整合 JPA:[https://github.com/itwanger/codingmore-learning](https://github.com/itwanger/codingmore-learning)
---
![](http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png)
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册