亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring AOP統(tǒng)一功能處理示例代碼

 更新時間:2023年01月17日 11:01:01   作者:https://blog.csdn.net/qq_43398758/article/details/125372404  
AOP面向切面編程,它是一種思想,它是對某一類事情的集中處理,而AOP是一種思想,而Spring AOP是一個框架,提供了一種對AOP思想的實現(xiàn),它們的關(guān)系和loC與DI類似,這篇文章主要介紹了Spring AOP統(tǒng)一功能處理示例代碼,需要的朋友可以參考下

1. 什么是Spring AOP?

在介紹Spring AOP之前,首先要了解一下什么是AOP?

AOP (Aspect Oriented Programming)︰面向切面編程,它是一種思想,它是對某一類事情的集中處理。比如用戶登錄權(quán)限的效驗,沒學(xué)AOP之前,我們所有需要判斷用戶登錄的頁面(中的方法),都要各自實現(xiàn)或調(diào)用用戶驗證的方法,然而有了AOP之后,我們只需要在某一處配置一下,所有需要判斷用戶登錄頁面(中的方法)就全部可以實現(xiàn)用戶登錄驗證了,不再需要每個方法中都寫相同的用戶登錄驗證了。

而AOP是一種思想,而Spring AOP是一個框架,提供了一種對AOP思想的實現(xiàn),它們的關(guān)系和loC與DI類似。

2. 為什要用 AOP?

我們之前的處理方式是每個Controller都要寫一遍用戶登錄驗證,然而當(dāng)你的功能越來越多,那么你要寫的登錄驗證也越來越多,而這些方法又是相同的,這么多的方法就會代碼修改和維護(hù)的成本。那有沒有簡單的處理方案呢?答案是有的,對于這種功能統(tǒng)一,且使用的地方較多的功能,就可以考慮AOP來統(tǒng)一處理了。

除了統(tǒng)一的用戶登錄判斷之外,AOP還可以實現(xiàn):

  • 統(tǒng)一日志記錄
  • 統(tǒng)一方法執(zhí)行時間統(tǒng)計
  • 統(tǒng)一的返回格式設(shè)置
  • 統(tǒng)一的異常處理
  • 事務(wù)的開啟和提交等

也就是說使用AOP可以擴(kuò)充多個對象的某個能力,所以AOP可以說是OOP (Object OrientedProgramming,面向?qū)ο缶幊?的補充和完善。

3. Spring AOP 應(yīng)該怎么學(xué)習(xí)呢?

Spring AOP學(xué)習(xí)主要分為以下3個部分:
1.學(xué)習(xí)AOP是如何組成的?也就是學(xué)習(xí)AOP組成的相關(guān)概念。
2.學(xué)習(xí)Spring AOP使用。
3.學(xué)習(xí)Spring AOP實現(xiàn)原理。下面我們分別來看。

3.1AOP組成

3.1.1 切面(Aspect)

切面(Aspect)由切點(Pointcut)和通知(Advice)組成,它既包含了橫切邏輯的定義,也包括了連接點的定義。

切面是包含了:通知、切點和切面的類,相當(dāng)于AOP實現(xiàn)的某個功能的集合。

3.1.2 連接點(Join Point)

應(yīng)用執(zhí)行過程中能夠插入切面的一個點,這個點可以是方法調(diào)用時,拋出異常時,甚至修改字段時。切面代碼可以利用這些點插入到應(yīng)用的正常流程之中,并添加新的行為。

連接點相當(dāng)于需要被增強(qiáng)的某個AOP功能的所有方法。

3.1.3 切點(Pointcut)

Pointcut是匹配Join Point的謂詞。

Pointcut 的作用就是提供一組規(guī)則(使用AspectJ pointcut expression language來描述)來匹配Join Point,給滿足規(guī)則的Join Point添加Advice。

切點相當(dāng)于保存了眾多連接點的一個集合(如果把切點看成一個表,而連接點就是表中一條一條的數(shù)據(jù))。

3.1.4 通知(Advice)

切面也是有目標(biāo)的——它必須完成的工作。在AOP術(shù)語中,切面的工作被稱之為通知。
通知︰定義了切面是什么,何時使用,其描述了切面要完成的工作,還解決何時執(zhí)行這個工作的問題。

Spring切面類中,可以在方法上使用以下注解,會設(shè)置方法為通知方法,在滿足條件后會通知本方法進(jìn)行調(diào)用:

  • 前置通知使用@Before:通知方法會在目標(biāo)方法調(diào)用之前執(zhí)行。
  • 后置通知使用@After:通知方法會在目標(biāo)方法返回或者拋出異常后調(diào)用。
  • 返回之后通知使用@AfterReturning:通知方法會在目標(biāo)方法返回后調(diào)用。
  • 拋異常后通知使用@AfterThrowing:通知方法會在目標(biāo)方法拋出異常后調(diào)用。
  • 環(huán)繞通知使用@Around:通知包裹了被通知的方法,在被通知的方法通知之前和調(diào)用之后執(zhí)行自定義的行為。

切點相當(dāng)于要增強(qiáng)的方法。
AOP整個組成部分的概念如下圖所示,以多個頁面都要訪問用戶登錄權(quán)限為例:

在這里插入圖片描述

3.2 Spring AOP實現(xiàn)

使用Spring AOP來實現(xiàn)一下AOP的功能,完成的目標(biāo)是攔截所有UserController里面的方法,每次調(diào)用UserController中任意一個方法時,都執(zhí)行相應(yīng)的通知事件。

Spring AOP 的實現(xiàn)步驟是:

  • 添加 AOP 框架支持。
  • 定義切面和切點。
  • 定義通知。

3.2.1 添加 AOP 框架支持

3.2.2 定義切面和切點。

3.2.3 定義相關(guān)通知

通知定義的是被攔截的方法具體要執(zhí)行的業(yè)務(wù),比如用戶登錄權(quán)限驗證方法就是具體要執(zhí)行的業(yè)務(wù)Spring AOP中,可以在方法上使用以下注解,會設(shè)置方法為通知方法,在滿足條件后會通知本方法進(jìn)行調(diào)用:

  • 前置通知使用@Before:通知方法會在目標(biāo)方法調(diào)用之前執(zhí)行。
  • 后置通知使用@After:通知方法會在目標(biāo)方法返回或者拋出異常后調(diào)用。
  • 返回之后通知使用@AfterReturning:通知方法會在目標(biāo)方法返回后調(diào)用。
  • 拋異常后通知使用@AfterThrowing:通知方法會在目標(biāo)方法拋出異常后調(diào)用。
  • 環(huán)繞通知使用@Around:通知包裹了被通知的方法,在被通知的方法通知之前和調(diào)用之后執(zhí)行自定義的行為。

具體實現(xiàn)如下:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class UserAspect {
    // 定義切點?法
    @Pointcut("execution(* com.example.demo.controller.UserController.*
(..))")
    public void pointcut(){ }
    // 前置通知
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("執(zhí)? Before ?法");
    }
    // 后置通知
    @After("pointcut()")
    public void doAfter(){
        System.out.println("執(zhí)? After ?法");
    }
    // return 之前通知
    @AfterReturning("pointcut()")
    public void doAfterReturning(){
        System.out.println("執(zhí)? AfterReturning ?法");
    }
    // 拋出異常之前通知
    @AfterThrowing("pointcut()")
    public void doAfterThrowing(){
        System.out.println("執(zhí)? doAfterThrowing ?法");
    }
    
    // 添加環(huán)繞通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint){
        Object obj = null;
        System.out.println("Around ?法開始執(zhí)?");
        try {
            // 執(zhí)?攔截?法
           obj = joinPoint.proceed();
           } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("Around ?法結(jié)束執(zhí)?");
        return obj;
    }
}

3.3 Spring AOP 實現(xiàn)原理

3.3.1 動態(tài)代理

Spring AOP是構(gòu)建在動態(tài)代理基礎(chǔ)上,因此Spring對AOP的支持局限于方法級別的攔截。

Spring AOP支持JDK ProxyCGLIB方式實現(xiàn)動態(tài)代理。默認(rèn)情況下,實現(xiàn)了接口的類,使用AOP會基于JDK生成代理類,沒有實現(xiàn)接口的類,會基于CGLIB生成代理類。

在這里插入圖片描述

這兩種方式的代理目標(biāo)都是被代理類中的方法,在運行期,動態(tài)的織入字節(jié)碼生成代理類

3.3.2 JDK和CGLIB實現(xiàn)的區(qū)別

  • JDK實現(xiàn),要求被代理類必須實現(xiàn)接口,之后是通過InvocationHandlerProxy,在運行時動態(tài)的在內(nèi)存中生成了代理類對象,該代理對象是通過實現(xiàn)同樣的接口實現(xiàn)(類似靜態(tài)代理接口實現(xiàn)的方式),只是該代理類是在運行期時,動態(tài)的織入統(tǒng)一的業(yè)務(wù)邏輯字節(jié)碼來完成。
  • CGLIB實現(xiàn),被代理類可以不實現(xiàn)接口,是通過繼承被代理類,在運行時動態(tài)的生成代理類

3.3.3 織入(Weaving):代理的生成時機(jī)

織入是把切面應(yīng)用到目標(biāo)對象并創(chuàng)建新的代理對象的過程,切面在指定的連接點被織入到目標(biāo)對象中。

在目標(biāo)對象的生命周期里有多個點可以進(jìn)行織入∶

  • 編譯期:切面在目標(biāo)類編譯時被織入。這種方式需要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。
  • 類加載器:切面在目標(biāo)類加載到JVM時被織入。這種方式需要特殊的類加載器 (ClassLoader),它可以在目標(biāo)類被引入應(yīng)用之前增強(qiáng)該目標(biāo)類的字節(jié)碼。AspectJ5的加載時織入(load-time weaving. LTW)就支持以這種方式織入切面。
  • 運行期:切面在應(yīng)用運行的某一時刻被織入。一般情況下,在織入切面時,AOP容器會為目標(biāo)對象動態(tài)創(chuàng)建一個代理對象。SpringAOP就是以這種方式織入切面的。

此種實現(xiàn)在設(shè)計模式上稱為動態(tài)代理模式,在實現(xiàn)的技術(shù)手段上,都是在class代碼運行期,動態(tài)的織入字節(jié)碼生成代理類。

3.3.4 總結(jié)

AOP是對某方面能力的統(tǒng)一實現(xiàn),它是一種實現(xiàn)思想,Spring AOP是對AOP的具體實現(xiàn),SpringAOP可通過AspectJ(注解) 的方式來實現(xiàn)AOP的功能,Spring AOP 的實現(xiàn)步驟是:

  • 添加AOP框架支持。
  • 定義切面和切點。
  • 定義通知。

Spring AOP是通過動態(tài)代理的方式,在運行期將AOP代碼織入到程序中的,它的實現(xiàn)方式有兩種JDK Proxy和CGLIB。

4. SpringBoot 統(tǒng)一功能處理

接下來是Spring Boot統(tǒng)一功能處理模塊了,也是AOP的實戰(zhàn)環(huán)節(jié),要實現(xiàn)的課程目標(biāo)有以下3個:

  • 統(tǒng)一用戶登錄權(quán)限驗證;
  • 統(tǒng)—數(shù)據(jù)格式返回;
  • 統(tǒng)一異常處理。

接下我們一個一個來看。

4.1 用戶登錄權(quán)限效驗

用戶登錄權(quán)限的發(fā)展從之前每個方法中自己驗證用戶登錄權(quán)限,到現(xiàn)在統(tǒng)一的用戶登錄驗證處理,它是—個逐漸完善和逐漸優(yōu)化的過程。

4.1.1 Spring攔截器

Spring 中提供了具體的實現(xiàn)攔截器:HandlerInterceptor,

統(tǒng)一用戶登錄權(quán)限的效驗使用WebMvcConfigurer + HandlerInterceptor來實現(xiàn)。

攔截器的實現(xiàn)分為以下兩個步驟∶

  • 創(chuàng)建自定義攔截器,實現(xiàn) HandlerInterceptor接口的preHandle (執(zhí)行具體方法之前的預(yù)處理)方法。
  • 將自定義攔截器加入 WebMvcConfigurer的addInterceptors方法中。具體實現(xiàn)如下。

4.1.2 自定義攔截器

接下來使用代碼來實現(xiàn)一個用戶登錄的權(quán)限效驗,自定義攔截器是一個普通類,具體實現(xiàn)代碼如下

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, 
HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("userinfo") != null) {
            return true;
        }
        response.setStatus(401);
        return false;
    }
}

4.1.3 將自定義攔截器加入到系統(tǒng)配置

將上一步中的自定義攔截器加入到系統(tǒng)配置信息中,具體實現(xiàn)代碼如下:

@Configuration
public class AppConfig implements WebMvcConfigurer {
    // 添加攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**") // 攔截所有接?
                .excludePathPatterns("/art/param11"); // 排除接?
    }
}

其中:

  • addPathPatterns:表示需要攔截的URL,“**”表示攔截任意方法(也就是所有方法)。
  • excludePathPatterns:表示需要排除的URL。

說明:以上攔截規(guī)則可以攔截此項目中的使用URL,包括靜態(tài)文件(圖片文件、JS和CSS等文件
排除所有的靜態(tài)資源

// 攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginInterceptor())
        .addPathPatterns("/**") // 攔截所有接?
        .excludePathPatterns("/**/*.js")
        .excludePathPatterns("/**/*.css")
        .excludePathPatterns("/**/*.jpg")
        .excludePathPatterns("/login.html")
        .excludePathPatterns("/**/login"); // 排除接?
}

4.1.4 攔截器實現(xiàn)原理

正常情況下的調(diào)用順序:

在這里插入圖片描述

然而有了攔截器之后,會在調(diào)用Controller 之前進(jìn)行相應(yīng)的業(yè)務(wù)處理,執(zhí)行的流程如下圖所示:

在這里插入圖片描述

4.1.5 攔截器小結(jié)

通過上面的源碼分析,我們可以看出,Spring 中的攔截器也是通過動態(tài)代理環(huán)繞通知的思想實現(xiàn)的大體的調(diào)用流程如下:

在這里插入圖片描述

4.1.6 擴(kuò)展:統(tǒng)?訪問前綴添加

所有請求地址添加 api 前綴:

@Configuration
public class AppConfig implements WebMvcConfigurer {
    // 所有的接?添加 api 前綴
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("api", c -> true);
    }
}

@Configuration
public class AppConfig implements WebMvcConfigurer {
    // 所有的接?添加 api 前綴
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("api", c -> true);
    }
}

其中第二個參數(shù)是?個表達(dá)式,設(shè)置為 true 表示啟動前綴。

4.2 統(tǒng)一異常處理

統(tǒng)一異常處理使用的是 @ControllerAdvice + @ExceptionHandler 來實現(xiàn)的,
@ControllerAdvice表示控制器通知類,@ExceptionHandler是異常處理器,兩個結(jié)合表示當(dāng)出現(xiàn)異常的時候執(zhí)行某個通知就是執(zhí)行某個方法事件,具體實現(xiàn)代碼如下:

import java.util.HashMap;

@ControllerAdvice
public class ErrorAdive {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handler(Exception e) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("success", 0);
        map.put("status", 1);
        map.put("msg", e.getMessage());
        return map;
    }
}

PS:方法名和返回值可以自定義,其中最重要的是@ExceptionHandler(Exception.class)注解.

以上方法表示,如果出現(xiàn)了異常就返回給前端一個HashMap的對象,其中包含的字段如代碼中定義的那樣。
我們可以針對不同的異常,返回不同的結(jié)果,比以下代碼所示:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;

@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {
    @ExceptionHandler(Exception.class)
    public Object exceptionAdvice(Exception e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("success", -1);
        result.put("message", "總的異常信息:" + e.getMessage());
        result.put("data", null);
        return result;
    }
    @ExceptionHandler(NullPointerException.class)
    public Object nullPointerexceptionAdvice(NullPointerException e) {
        HashMap<String, Object> result = new HashMap<>();
        result.put("success", -1);
        result.put("message", "空指針異常:" + e.getMessage());
        result.put("data", null);
        return result;
    }
}

當(dāng)有多個異常通知時,匹配順序為當(dāng)前類及其子類向上依次匹配,案例演示。在UserController中設(shè)置一個空指針異常,實現(xiàn)代碼如下:

@RestController
@RequestMapping("/u")
public class UserController {
    @RequestMapping("/index")
    public String index() {
        Object obj = null;
        int i = obj.hashCode();
        return "Hello,User Index.";
    }
}

以上程序的執(zhí)行結(jié)果如下:

在這里插入圖片描述

4.2 統(tǒng)一數(shù)據(jù)返回格式

4.2.1 為什么需要統(tǒng)一數(shù)據(jù)返回格式?

統(tǒng)一數(shù)據(jù)返回格式的優(yōu)點有很多,比如以下幾個:

  • 方便前端程序員更好的接收和解析后端數(shù)據(jù)接口返回的數(shù)據(jù)。
  • 降低前端程序員和后端程序員的溝通成本,這按照某個格式實現(xiàn)就行了,因為所有接口都是這樣返回的。
  • 有利于項目統(tǒng)—數(shù)據(jù)的維護(hù)和修改。
  • 有利于后端技術(shù)部門的統(tǒng)一規(guī)范的標(biāo)準(zhǔn)制定,不會出現(xiàn)稀奇古怪的返回內(nèi)容。

4.2.2 統(tǒng)一數(shù)據(jù)返回格式的實現(xiàn)

統(tǒng)一的數(shù)據(jù)返回格式可以使用
@ControllerAdvice + ResponseBodyAdvice 的方式實現(xiàn),具體實現(xiàn)代碼如下:

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    /**
     * 內(nèi)容是否需要重寫(通過此?法可以選擇性部分控制器和?法進(jìn)?重寫)
     * 返回 true 表示重寫
     */
    @Override
    public boolean supports(MethodParameter returnType, Class 
converterType) {
        return true;
    }
    /**
     * ?法返回之前調(diào)?此?法
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter 
		returnType, MediaType selectedContentType, Class selectedConverterType, 
		ServerHttpRequest request, ServerHttpResponse response) {
        // 構(gòu)造統(tǒng)?返回對象
        HashMap<String, Object> result = new HashMap<>();
        result.put("success", 1);
        result.put("message", "");
        result.put("data", body);
        return result;
    }
}

總結(jié)

  • 統(tǒng)一用戶登錄權(quán)限的效驗使用WebMvcConfigurer + HandlerInterceptor來實現(xiàn),
  • 統(tǒng)一異常處理使用 @ControllerAdvice + @ExceptionHandler 來實現(xiàn),
  • 統(tǒng)一返回值處理使用 @ControllerAdvice + ResponseBodyAdvice 來處理。

到此這篇關(guān)于Spring AOP統(tǒng)一功能處理的文章就介紹到這了,更多相關(guān)Spring AOP用戶登陸統(tǒng)一驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Integer方法實例詳解

    Java中Integer方法實例詳解

    這篇文章主要給大家介紹了關(guān)于Java中Integer方法的相關(guān)資料,Java中的Integer是int的包裝類型,文中通過代碼實例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • SpringBoot+Elasticsearch實現(xiàn)數(shù)據(jù)搜索的方法詳解

    SpringBoot+Elasticsearch實現(xiàn)數(shù)據(jù)搜索的方法詳解

    Elasticsearch是一個基于Lucene的搜索服務(wù)器。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful?web接口。本文將利用SpringBoot整合Elasticsearch實現(xiàn)海量級數(shù)據(jù)搜索,需要的可以參考一下
    2022-05-05
  • spring級聯(lián)屬性賦值的兩種方式解析

    spring級聯(lián)屬性賦值的兩種方式解析

    這篇文章主要介紹了spring級聯(lián)屬性賦值的兩種方式解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • SpringBoot實現(xiàn)ORM操作MySQL的幾種方法

    SpringBoot實現(xiàn)ORM操作MySQL的幾種方法

    本文主要介紹了SpringBoot實現(xiàn)ORM操作MySQL的幾種方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 如何解決Mybatis-plus中@TableLogic注解失效問題

    如何解決Mybatis-plus中@TableLogic注解失效問題

    這篇文章主要介紹了如何解決Mybatis-plus中@TableLogic注解失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 淺談spring.factories文件的作用

    淺談spring.factories文件的作用

    本文主要介紹了淺談spring.factories文件的作用,spring.factories文件是Spring?Boot自動配置的核心文件之一,它的作用是將各種自動配置類與對應(yīng)的配置類集中在一起,下面就來介紹一下如何使用,感興趣的可以了解一下
    2024-06-06
  • Java 多線程之間共享數(shù)據(jù)

    Java 多線程之間共享數(shù)據(jù)

    這篇文章主要介紹了Java 多線程之間共享數(shù)據(jù),圍繞Java 多線程之間共享數(shù)據(jù)展開文章內(nèi)容線程范圍的共享變量、使用Map實現(xiàn)線程范圍內(nèi)數(shù)據(jù)的共享、ThreadLocal實現(xiàn)線程范圍內(nèi)數(shù)據(jù)的共享,需要的朋友可以參考一下
    2021-10-10
  • SpringCloud超詳細(xì)講解微服務(wù)網(wǎng)關(guān)Gateway

    SpringCloud超詳細(xì)講解微服務(wù)網(wǎng)關(guān)Gateway

    這篇文章主要介紹了SpringCloud Gateway微服務(wù)網(wǎng)關(guān),負(fù)載均衡,熔斷和限流,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • java編程簡單獲取圖片像素的方法

    java編程簡單獲取圖片像素的方法

    這篇文章主要介紹了java編程簡單獲取圖片像素的方法,涉及Java針對圖片的讀取與屬性獲取技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Mybatis空值關(guān)聯(lián)的問題解析及解決方案

    Mybatis空值關(guān)聯(lián)的問題解析及解決方案

    這篇文章給大家介紹了Mybatis空值關(guān)聯(lián)的問題解析及解決方案,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01

最新評論