java文件上傳時給pdf、word、excel、ppt、圖片添加水印

前言

在開發的過程中,因為文件的特殊性,需要給pdf、word、excel、ppt、圖片添加水印。添加水印可以在文件上傳時添加,也可以在文件下載時添加。因為業務的某些原因,文件需要在瀏覽器預覽,如果用戶將文件另存為則無法添加水印,所以此文章主要介紹文件上傳時添加水印。至于文件下載時添加水印功能也很簡單,稍微修改即可。

一:文件上傳

1.1 controller控制層

@ApiOperation("上傳文件")@PostMapping("/file/upload")public String uploadFile(@RequestParam(value = "file") MultipartFile file) {if (file == null || file.isEmpty()) {throw new BusinessException("上傳文件為空");}String originalFilename = file.getOriginalFilename();if (StringUtils.isBlank(originalFilename)) {throw new BusinessException("上傳文件名為空");}String filePath = obsClientHelper.upload(file, file.getOriginalFilename());return filePath;}

1.2 文件上傳到服務器

/*** 上傳文件到服務器** @param uploadFile 文件* @param fileName   文件名稱* @return 文件路徑*/@SneakyThrowspublic String upload(MultipartFile uploadFile, String fileName) {String objectKey = directory + "/" + DATE_TIME_FORMATTER.format(LocalDate.now()) + "/" + UUID.randomUUID() + "/" + fileName;InputStream inputStream = null;//上傳文件添加水印SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String watermark = UserContext.currentUser().getUserName() + "(" + UserContext.currentUser().getUserId() + ")" + "\n" + simpleDateFormat.format(new Date());if (fileName.endsWith("pdf")) {inputStream = PdfWatermarkUtils.addWatermarkInputStream(uploadFile.getInputStream(), new PdfWatermarkPageEventHelper(watermark));} else if (fileName.endsWith(ImageConstants.PICTURE_JPG) || fileName.endsWith(ImageConstants.PICTURE_PNG)) {inputStream = ImageWatermarkUtil.imgWatermarkInputStream(watermark, uploadFile.getInputStream(), -40);} else if (fileName.endsWith("docx") || fileName.endsWith("xlsx") || fileName.endsWith("pptx")) {TextWaterMarkDTO waterMarkDTO = new TextWaterMarkDTO(fileName, watermark);inputStream = OfficeWatermarkUtil.doMarkInputStream(uploadFile.getInputStream(), waterMarkDTO);} else {inputStream = uploadFile.getInputStream();}if (inputStream == null) {throw new RuntimeException("上傳文件時,文件添加水印失敗");}try (ObsClient obsClient = new ObsClient(ak, sk, endPoint)) {PutObjectResult putObjectResult = obsClient.putObject(bucketName, objectKey, inputStream);if (putObjectResult.getStatusCode() != HttpServletResponse.SC_OK) {throw new RuntimeException("文件上傳失敗,OBS響應碼:" + putObjectResult.getStatusCode());}return putObjectResult.getObjectKey();} catch (IOException e) {throw new RuntimeException("文件上傳失敗", e);}}

二:PDF添加水印

2.1 引入依賴

<dependency><groupId>com.itextpdf</groupId><artifactId>kernel</artifactId><version>7.1.11</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>layout</artifactId><version>7.1.11</version></dependency><!--沒有該包的話,會有中文顯示問題--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.3</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>com.itextpdf.tool</groupId><artifactId>xmlworker</artifactId><version>5.5.11</version></dependency>

2.2 PdfWatermarkUtils

/*** pdf加水印* @param inputStream 輸入流* @param pdfPageEventHelper 水印* @return InputStream* @throws IOException*/public static InputStream addWatermarkInputStream(InputStream inputStream, PdfPageEventHelper pdfPageEventHelper) throws IOException {String watermarkText = ((PdfWatermarkPageEventHelper) pdfPageEventHelper).getWatermarkText();float fontSize = 13;int rowSpace = 150;int colSpace = 150;boolean linux = SystemUtil.getOsInfo().isLinux();String chineseFontPath = null;if (linux) {chineseFontPath = "/usr/share/fonts/STSONG.TTF";} else {chineseFontPath = SystemUtil.getUserInfo().getCurrentDir() + "\\fonts\\STSONG.TTF";}watermarkText = watermarkText.replace("\n", "  ");// 加載PDF文件PDDocument document = PDDocument.load(inputStream);document.setAllSecurityToBeRemoved(true);// 加載水印字體PDFont font = PDType0Font.load(document, new FileInputStream(chineseFontPath), true);// 遍歷PDF文件,在每一頁加上水印for (PDPage page : document.getPages()) {PDPageContentStream stream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);PDExtendedGraphicsState r = new PDExtendedGraphicsState();// 設置透明度r.setNonStrokingAlphaConstant(0.2f);r.setAlphaSourceFlag(true);stream.setGraphicsStateParameters(r);// 設置水印字體顏色stream.setStrokingColor(Color.GRAY);stream.beginText();stream.setFont(font, fontSize);stream.newLineAtOffset(0, -15);// 獲取PDF頁面大小float pageHeight = page.getMediaBox().getHeight();float pageWidth = page.getMediaBox().getWidth();// 根據紙張大小添加水印,30度傾斜for (int h = 10; h < pageHeight; h = h + rowSpace) {for (int w = -10; w < pageWidth; w = w + colSpace) {stream.setTextMatrix(Matrix.getRotateInstance(0.3, w, h));stream.showText(watermarkText);}}// 結束渲染,關閉流stream.endText();stream.restoreGraphicsState();stream.close();}return pdDocumentConvertorStream(document);}
/*** 將PDDocument轉化為InputStream** @param document document* @return InputStream*/public static InputStream pdDocumentConvertorStream(PDDocument document) {try {//臨時緩沖區ByteArrayOutputStream out = new ByteArrayOutputStream();document.save(out);document.close();return new ByteArrayInputStream(out.toByteArray());} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

三:圖片添加水印

3.1 ImageWatermarkUtil

import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Objects;@Component
@Slf4j
public class ImageWatermarkUtil {/*** 水印透明度*/private static final float ALPHA = 0.5f;/*** 水印文字大小*/public static final int FONT_SIZE = 23;/*** 水印文字字體*/private static Font FONT;/*** 水印文字顏色*/private static final Color COLOR = Color.white;/*** 水印之間的間隔*/private static final int X_MOVE = 60;/*** 水印之間的間隔*/private static final int Y_MOVE = 60;/*** 獲取文本長度。漢字為1:1,英文和數字為2:1*/private static int getTextLength(String text) {int length = text.length();for (int i = 0; i < text.length(); i++) {String s = String.valueOf(text.charAt(i));if (s.getBytes().length > 1) {length++;}}length = length % 2 == 0 ? length / 2 : length / 2 + 1;return length;}/*** 圖片添加水印** @param logoText         水印內容* @param sourceFileStream 流文件* @param degree           傾斜角度* @return InputStream*/public static InputStream imgWatermarkInputStream(String logoText, InputStream sourceFileStream, Integer degree) {try {BufferedImage bufferedImage = addWatermark(logoText, sourceFileStream, degree);ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "jpg", os);return new ByteArrayInputStream(os.toByteArray());} catch (IOException e) {return null;}}/*** 圖片添加水印** @param logoText         水印內容* @param sourceFileStream 流文件* @param degree           傾斜角度* @return BufferedImage*/public static BufferedImage addWatermark(String logoText, InputStream sourceFileStream, Integer degree) throws IOException {//源圖片Image srcImg = ImageIO.read(sourceFileStream);//原圖寬度int width = srcImg.getWidth(null);//原圖高度int height = srcImg.getHeight(null);BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null),BufferedImage.TYPE_INT_RGB);// 得到畫筆對象Graphics2D g = buffImg.createGraphics();// 設置對線段的鋸齒狀邊緣處理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH),0, 0, null);// 設置水印旋轉if (null != degree) {g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);}// 設置水印文字顏色g.setColor(COLOR);// 設置水印文字Fontg.setFont(FONT);// 設置水印文字透明度g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));int x = -width / 2;int y = -height / 2;// 字體長度int markWidth = FONT_SIZE * getTextLength(logoText);// 字體高度// 循環添加水印while (x < width * 1.5) {y = -height;while (y < height * 1.5) {String[] lines = logoText.split("\n");for (String line : lines) {g.drawString(line, x, y);y += FONT_SIZE + Y_MOVE;}}x += markWidth + X_MOVE;}// 釋放資源g.dispose();return buffImg;}/*** 給圖片添加水印文字、可設置水印文字的旋轉角度** @param logoText         水印內容* @param sourceFileStream 輸入流文件* @param targetFileStream 輸出流文件* @param degree           傾斜角度*/public static void imageByText(String logoText, InputStream sourceFileStream, OutputStream targetFileStream, Integer degree) {if (Objects.isNull(FONT)) {FONT = new Font(FontUtil.firstZhSupportedFontName(), Font.BOLD, FONT_SIZE);}try {// 生成圖片ImageIO.write(addWatermark(logoText, sourceFileStream, degree), "JPG", targetFileStream);log.info("圖片-添加水印文字成功!");} catch (Exception e) {e.printStackTrace();} finally {try {if (null != targetFileStream) {targetFileStream.close();}} catch (Exception e) {e.printStackTrace();}}}}

3.2 FontUtil

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;import java.awt.*;
import java.util.Arrays;@Slf4j
public class FontUtil {private static String ZH_SUP;static {GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();char randomZh = '唐';Font[] allFonts = ge.getAllFonts();for (Font font : allFonts) {if(font.canDisplay(randomZh)){ZH_SUP = font.getFontName();break;}}if(StringUtils.isEmpty(ZH_SUP)){log.error("Zh supported font not found");ZH_SUP = allFonts[0].getFontName();}}public static String firstZhSupportedFontName(){return ZH_SUP;}public static java.util.List<String> getAllFontNames(){GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();String[] availableFontFamilyNames = ge.getAvailableFontFamilyNames();return Arrays.asList(availableFontFamilyNames);}
}

四:docx、xlsx、pptx添加水印

注:ppt、xls、doc由于版本新舊問題,此處先不介紹添加水印方法

4.1 TextWaterMarkDTO

import com.FontUtil;
import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class TextWaterMarkDTO{public TextWaterMarkDTO() {this.fontName = FontUtil.firstZhSupportedFontName();}public TextWaterMarkDTO(String fileName,String text) {this.fontName = FontUtil.firstZhSupportedFontName();this.fileSuffix = loadFileSuffix(fileName);this.text = text;}String fileSuffix;private String text;private String fontName;private String fontColor;private Integer fontSize = 20;private Integer rotation = -20;Integer intervalHorizontal;Integer intervalVertical;Integer picWidth;Integer picHeight;Float alpha;boolean enable;private String loadFileSuffix(String fileName){String realName = fileName.trim();int index = realName.lastIndexOf(".");if( index < 0){return null;}return fileName.substring(index + 1);}}

4.2 doMarkInputStream

/*** 添加文件水印,返回InputStream** @param input         輸入流* @param waterMarkInfo waterMarkInfo* @return InputStream*/public static InputStream doMarkInputStream(InputStream input, TextWaterMarkDTO waterMarkInfo) {InputStream inputStream = null;try {String fileSuffix = waterMarkInfo.getFileSuffix().toLowerCase();switch (fileSuffix) {case "docx":inputStream = docxWaterMarkInputStream(input, waterMarkInfo);break;case "xlsx":log.info("xlsx");inputStream = xlsxWaterMarkInputStream(input, waterMarkInfo.setPicWidth(1000).setPicHeight(2000));break;case "pptx":log.info("pptx");inputStream = pptxAddWatermarkInputStream(input, waterMarkInfo);break;default:log.info("in default. fileSuffix:{}", fileSuffix);inputStream = input;}return inputStream == null ? input : inputStream;} catch (Exception e) {log.error(ExceptionUtil.stacktraceToString(e));return null;} finally {close(input);}}

4.3 docx

@SneakyThrowsprivate static InputStream docxWaterMarkInputStream(InputStream input, TextWaterMarkDTO waterMarkInfo) {XWPFDocument docx = new XWPFDocument(input);//設置默認值String watermark = StringUtils.isBlank(waterMarkInfo.getText()) ? DEFAULT_WATERMARK : waterMarkInfo.getText();String color = StringUtils.isBlank(waterMarkInfo.getFontColor()) ? DEFAULT_FONT_COLOR : "#" + waterMarkInfo.getFontColor();String fontSize = (null == waterMarkInfo.getFontSize()) ? FONT_SIZE : waterMarkInfo.getFontSize() + "pt";String rotation = (null == waterMarkInfo.getRotation()) ? STYLE_ROTATION : String.valueOf(waterMarkInfo.getRotation());DocxUtil.makeFullWaterMarkByWordArt(docx, watermark, color, fontSize, rotation);//將XWPFDocument轉化為InputStreamreturn convertToInputStream(docx);}
/*** 將XWPFDocument轉化為InputStream** @param doc XWPFDocument* @return InputStream*/public static InputStream convertToInputStream(XWPFDocument doc) {try {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();doc.write(outputStream);return new ByteArrayInputStream(outputStream.toByteArray());} catch (IOException e) {log.error(e.getMessage(), e);return null;}}

4.4 xlsx

@SneakyThrowsprivate static InputStream xlsxWaterMarkInputStream(InputStream input, TextWaterMarkDTO waterMark) {XSSFWorkbook workbook = new XSSFWorkbook(input);Iterator<Sheet> iterator = workbook.sheetIterator();BufferedImage image = FontImage.createWatermarkImageFillWithText(waterMark);ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);while (iterator.hasNext()) {XSSFSheet sheet = (XSSFSheet) iterator.next();String rID = sheet.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx)).getRelationship().getId();//set background picture to sheetsheet.getCTWorksheet().addNewPicture().setId(rID);}//將XSSFWorkbook轉化為InputStreamreturn workbookConvertorStream(workbook);}
/*** 將XSSFWorkbook轉化為InputStream** @param workbook XSSFWorkbook* @return InputStream*/public static InputStream workbookConvertorStream(XSSFWorkbook workbook) {try {//臨時緩沖區ByteArrayOutputStream out = new ByteArrayOutputStream();//創建臨時文件workbook.write(out);byte[] bookByteAry = out.toByteArray();return new ByteArrayInputStream(bookByteAry);} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

4.5 pptx

@SneakyThrowsprivate static InputStream pptxAddWatermarkInputStream(InputStream input, TextWaterMarkDTO waterMarkDto) {XMLSlideShow slideShow = new XMLSlideShow(input);waterMarkDto.setPicWidth(Double.valueOf(slideShow.getPageSize().width).intValue());waterMarkDto.setPicHeight(Double.valueOf(slideShow.getPageSize().height).intValue());BufferedImage image = FontImage.createWatermarkImageFillWithText(waterMarkDto);ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(image, "png", os);PictureData pictureData1 = slideShow.addPicture(os.toByteArray(), PictureData.PictureType.PNG);for (XSLFSlide slide : slideShow.getSlides()) {XSLFPictureShape pictureShape = slide.createPicture(pictureData1);pictureShape.setAnchor(new Rectangle(0, 0, slideShow.getPageSize().width, slideShow.getPageSize().height));}return xmlSlideShowConvertorStream(slideShow);}
/*** 將XMLSlideShow轉化為InputStream** @param slideShow slideShow* @return InputStream*/public static InputStream xmlSlideShowConvertorStream(XMLSlideShow slideShow) {try {//臨時緩沖區ByteArrayOutputStream out = new ByteArrayOutputStream();//創建臨時文件slideShow.write(out);byte[] bookByteAry = out.toByteArray();return new ByteArrayInputStream(bookByteAry);} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/13863.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13863.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13863.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

算法與數據結構匯總

基本 數組 字符串 排序 矩陣 模擬 枚舉 字符串匹配 桶排序 計數排序 基數排序 回文&#xff1a;中心擴展 馬拉車 樹上啟發式合并 括號 數學表達式 字符串&#xff1a;前后綴分解。 貢獻法 分組&#xff1a; 【狀態機dp 狀態壓縮 分組】1994. 好子集的數目 【動態規劃】【前綴…

Excel中sum的跨表求和

#實際工作中&#xff0c;一個xlsx文件中會包含多個Excel表格&#xff0c;一般會有“總-分”的關系&#xff0c;如何把分表里的數字匯總到總表里呢&#xff1f; 一般有上圖所示的兩種表達方式。 可以使用通配符 *&#xff1a;代表任意個數、任意字符&#xff1b; &#xff1f;&…

51單片機的最小系統詳解

51單片機的最小系統詳解 1. 引言 在嵌入式系統中,51單片機被廣泛應用于各種小型控制器和嵌入式開發板中。相信很多人都接觸過51單片機,但是對于51單片機的最小系統卻了解得不夠深入。本文將從振蕩電路、電源模塊、復位電路、LED指示燈和調試接口五個方面詳細介紹51單片機的…

quartz定時任務

Quartz 數據結構 quartz采用完全二叉樹&#xff1a;除了最后一層每一層節點都是滿的&#xff0c;而且最后一層靠左排列。 二叉樹節點個數規則&#xff1a;每層從左開始&#xff0c;第一層只有一個&#xff0c;就是2的0次冪&#xff0c;第二層兩個就是2的1次冪&#xff0c;第三…

DOS學習-目錄與文件應用操作經典案例-attrib

新書上架~&#x1f447;全國包郵奧~ python實用小工具開發教程http://pythontoolsteach.com/3 歡迎關注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目錄 一.前言 二.使用 三.案例 一.前言 DOS系統中的attrib命令是一個用于顯示或更改文件&#…

設計模式——職責鏈(責任鏈)模式

目錄 職責鏈模式 小俱求實習 結構圖 實例 職責鏈模式優點 職責鏈模式缺點 使用場景 1.springmvc流程 ?2.mybatis的執行流程 3.spring的過濾器和攔截器 職責鏈模式 使多個對象都有機會處理請求&#xff0c;從而避免請求的發送者和接受者之間的耦合關系。將這個對象連成…

github設置項目分類

https://www.php.cn/faq/541957.html https://docs.github.com/zh/repositories/working-with-files/managing-files/creating-new-files

什么是回表,如何解決回表問題

下面表中:主鍵id是聚簇索引&#xff0c;name是輔助索引。 執行這樣一條SQL: select name from A where name"s;name字段是有索引&#xff0c;所以MYSQL在通過name進行査詢的時候&#xff0c;是需要掃描兩顆Btree樹的。 第一遍:先通過二級索引定位主鍵值1。第二遍:根據主鍵…

免費發布web APP的四個途徑(Python和R)

免費發布數據分析類&#x1f310;web APP的幾個途徑&#x1f4f1; 數據分析類web APP目前用來部署生信工具&#xff0c;統計工具和預測模型等&#xff0c;便利快捷&#xff0c;深受大家喜愛。而一個免費的APP部署途徑&#xff0c;對于開發和測試APP都是必要的。根據筆者的經驗…

word-形狀繪制、smartart、visio

一、人員架構圖繪制 小技巧&#xff1a; 1、ctrlshift水平復制 2、點擊圖形&#xff0c;右鍵設置為默認形狀 3、插入-形狀-右鍵-鎖定繪圖模式&#xff0c;按esc退出狀態 4、插入-形狀-新建繪圖畫布&#xff0c;代替組合問題 畫布中存在錨點&#xff0c;便于直線連接 二、s…

網絡安全相關面試題(hw)

網絡安全面試題 報錯注入有哪些函數 updatexml注入 載荷注入 insert注入 updata注入 delete注入 extractvalue&#xff08;&#xff09;注入 注入防御方法 涵數過濾 直接下載相關防范注入文件&#xff0c;通過incloud包含放在網站配置文件里面 PDO預處理,從PHP 5.1開始&…

electron中BrowserWindow的show事件沒有觸發踩坑記錄

class ElectronApi {static mainWindow;//主窗口createWindow() {try {// Create the browser window.this.mainWindow new BrowserWindow({width: 1200,height: 800,minHeight: 800,minWidth: 1200,webPreferences: {preload: preloadPath,// nodeIntegration: true,// conte…

windows怎么復制文件到vmware 中ubantu虛擬機,vmware中的虛擬機怎么聯網,NAT參數和DHCP參數。

目錄 windows怎么復制文件到vmware 中ubantu虛擬機 vmware中的虛擬機怎么聯網 NAT參數和DHCP參數。

Linux環境Docker安裝,使用Docker搭建Mysql服務實戰

1、環境&#xff1a;阿里云Linxu服務器 2、安裝docker # 1、yum 包更新到最新 yum update # 2、安裝需要的軟件包&#xff0c; yum-util 提供yum-config-manager功能&#xff0c;另外兩個是devicemapper驅動依賴的 yum install -y yum-utils device-mapper-persistent-data…

OpenSSL之API編程 - C/C++實現AES、DES、3DES、SM4對稱加密算法

文章介紹 本文章介紹了OpenSSL計算對稱加解密算法(AES、DES、3DES、SM4等)的相關接口&#xff0c;并使用C語言實現了AES和SM4加解密。 對稱加解密算法 對稱加密與非對稱加密算法 OpenSSL介紹 openssl是一個功能豐富且自包含的開源安全工具箱。它提供的主要功能有&#xff…

深度學習之基于YOLOV5的口罩檢測系統

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景 隨著全球公共衛生事件的頻發&#xff0c;口罩成為了人們日常生活中不可或缺的一部分。在公共場所&am…

10、SpringBoot 源碼分析 - 自動配置深度分析三

SpringBoot 源碼分析 - 自動配置深度分析三 refresh和自動配置大致流程AutoConfigurationImportSelector的getAutoConfigurationEntry獲取自動配置實體(重點)AutoConfigurationImportSelector的getCandidateConfigurations獲取EnableAutoConfiguration類型的名字集合AutoConfig…

Android中JVM內存回收機制

文章目錄 分代收集算法&#xff1a;新生代&#xff08;Young Generation&#xff09;老年代&#xff08;Old Generation&#xff09; 垃圾回收器&#xff1a;JVM常見三大回收算法&#xff1a;Mark-Sweep(標記清除)優點:缺點: 復制算法優點&#xff1a;缺點&#xff1a; Mark-Co…

ubuntu下交叉編譯安卓FFmpeg 和 官方指導鏈接

將之前的編譯方法在此記錄 Linux系統&#xff1a;Ubuntu 18.04.6 LTS 交叉編譯工具鏈&#xff1a;gcc-aarch64-linux-gnu gaarch64-linux-gnu ffmpeg版本&#xff1a;5.1.3 1.下載源碼 ffmpeg官網&#xff1a;https://ffmpeg.org/download.html#releases 下載完成后&#x…

Edge瀏覽器“此頁存在問題”解決思路

Edge瀏覽器顯示“此頁存在問題”解決思路 大家平時使用Edge瀏覽器時&#xff0c;是否和我一樣會突然出現“此頁存在問題”的情況&#xff1f; 經過百度查詢后我找了一種情況和解決辦法&#xff0c;能夠大大減少這類問題的出現。出現“此頁存在問題”可能是因為之前使用過軟件…