国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理

這篇具有很好參考價(jià)值的文章主要介紹了【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、必須知道的三大組件(Overview)

在 【深入淺出Spring Security(一)】Spring Security的整體架構(gòu) 中小編解釋過(guò)授權(quán)所用的三大組件,在此再解釋說(shuō)明一下(三大組件具體指:ConfigAttribute、AccessDecisionManager(決策管理器)、AccessDecisionVoter(決策投票器))

  • ConfigAttribute 在 Spring Security 中,用戶請(qǐng)求一個(gè)資源(通常是一個(gè)接口或者是一個(gè) java 方法)需要的角色會(huì)被封裝成一個(gè) ConfigAttribute 對(duì)象,在ConfigAttribute 中只有一個(gè) getAttribute 方法,該方法返回一個(gè) String 字符串,就是角色的名稱。一般來(lái)說(shuō),角色名稱都帶有一個(gè) ROLE_ 前綴,投票器 AccessDecisionVoter 所做的事情,其實(shí)就是比較用戶所具備的角色和請(qǐng)求某個(gè)資源所需的 ConfigAttribute 之間的關(guān)系。
  • AccessDecisionVoterAccessDecisionManager 都有眾多的實(shí)現(xiàn)類,在 AccessDecisionManager 中會(huì)挨個(gè)遍歷 AccessDecisionVoter,進(jìn)而決定是否允許用戶訪問(wèn),因而 AccessDecisionVoter 和 AccessDecisionManager 兩者的關(guān)系類似于 AuthenticationManager(ProviderManager) 和 AuthenticationProvider 的關(guān)系。

二、FilterSecurityInterceptor 源碼分析

小編在述說(shuō) 【深入淺出Spring Security(二)】Spring Security的實(shí)現(xiàn)原理 的時(shí)候,總結(jié)出了 Spring Security 中所用的過(guò)濾器,其中有個(gè) FilterSecurityInterceptor ,它是其默認(rèn)加載的一個(gè)過(guò)濾器(FilterSecurityInterceptor 雖繼承了 AbstractSecurityInterceptor,但同時(shí)也實(shí)現(xiàn)了 Filter,實(shí)現(xiàn)了其 doFilter 方法核心方法,并在 SecurityFilterChain 中,所以一般稱過(guò)濾器比較合適)。

(下圖展示了攔截請(qǐng)求的一流程,可以看完圖下的源碼分析后再回過(guò)頭看這張圖,會(huì)變得清晰很多。)

【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理

doFilter 方法具體實(shí)現(xiàn)

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 將request、response、chain三個(gè)對(duì)象封裝到一FilterInvocation中 
		// 然后再調(diào)用 invoke 方法
		invoke(new FilterInvocation(request, response, chain));
	}

invoke 方法具體實(shí)現(xiàn)

	public void invoke(FilterInvocation filterInvocation) throws IOException, ServletException {
		// 判斷用戶在此次請(qǐng)求中是否已經(jīng)被允許通過(guò)
		if (isApplied(filterInvocation) && this.observeOncePerRequest) {
			filterInvocation.getChain().doFilter(filterInvocation.getRequest(), filterInvocation.getResponse());
			return;
		}
		// 調(diào)用父類AbstractSecurityInterceptor 中的 beforeInvocation 方法
		// 傳入的參數(shù)是 filterInvocation 對(duì)象,是request、response、chain的封裝對(duì)象
		// 這個(gè)方法內(nèi)部就是實(shí)現(xiàn)路徑權(quán)限認(rèn)證操作
		InterceptorStatusToken token = super.beforeInvocation(filterInvocation);
		try {
			filterInvocation
			.getChain()
			.doFilter(filterInvocation.getRequest(),
			 filterInvocation.getResponse());
		}
		finally {
			super.finallyInvocation(token);
		}
		super.afterInvocation(token, null);
	}

beforeInvocation 方法核心代碼分析

	protected InterceptorStatusToken beforeInvocation(Object object) {
		// obtainSecurityMetadataSource() 方法獲取子類的 FilterInvocationSecurityMetadataSource 的對(duì)象
		// 然后通過(guò)獲取到的FilterInvocationSecurityMetadataSource對(duì)象調(diào)用getAttributes方法獲取 ConfigAttribute 集合
		// 集用戶要訪問(wèn)該資源需要的權(quán)限集(后面會(huì)對(duì)其進(jìn)行源碼分析,這里先知道是獲取訪問(wèn)該資源需要的權(quán)限集就行,上面(一)也做了解釋)
		Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object);
		if (CollectionUtils.isEmpty(attributes)) {
			return null; // no further work post-invocation
		}
		// 判斷是否已經(jīng)認(rèn)證過(guò)了,沒(méi)認(rèn)證重新認(rèn)證(重新認(rèn)證的Authentication對(duì)象是從SecurityContextHolder中獲取的)
		// 返回用戶認(rèn)證信息
		Authentication authenticated = authenticateIfRequired();
		// Attempt authorization
		// 嘗試對(duì)路徑進(jìn)行放行,即判斷請(qǐng)求路徑是否擁有訪問(wèn)權(quán)限
		attemptAuthorization(object, attributes, authenticated);
		// no further work post-invocation
		return new InterceptorStatusToken(SecurityContextHolder.getContext(), false, attributes, object);

	}

attemptAuthorization 方法源碼分析

	// 參數(shù)說(shuō)明:
	// 1. object是filterInvocation對(duì)象,即request、response、chain的封裝體
	// 2. attributes 是訪問(wèn)路徑需要的權(quán)限集
	// 3. authentication 用戶認(rèn)證的權(quán)限信息
	private void attemptAuthorization(Object object, Collection<ConfigAttribute> attributes,
			Authentication authenticated) {
		try {
			// 通過(guò) AccessDecisionManager 決策管理器對(duì)象進(jìn)行決策是否放行
			this.accessDecisionManager.decide(authenticated, object, attributes);
		}
		catch (AccessDeniedException ex) {
			publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated, ex));
			throw ex;
		}
	}

這是 AccessDecisionManager 的結(jié)構(gòu)圖,SpringSecurity 默認(rèn)實(shí)現(xiàn)是 AffirmativeBased(我看最新版本即6.1.0,這些全棄用了,估計(jì)是讓咱自身實(shí)現(xiàn)吧??)。

【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理

AffirmativeBased 中的 decide 方法源碼分析

	@Override
	public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException {
		// 否認(rèn)的一個(gè)標(biāo)志變量,用來(lái)判斷是否授權(quán)成功
		int deny = 0;
		// 遍歷 AccessDecisionVoter,看看是否能投票通過(guò)
		for (AccessDecisionVoter voter : getDecisionVoters()) {
			int result = voter.vote(authentication, object, configAttributes);
			switch (result) {
			// result 為 1 的話,就說(shuō)有該 AccessDecisionVoter 已經(jīng)投票通過(guò)了
			case AccessDecisionVoter.ACCESS_GRANTED:
				return;
			// result 為 0 的話,說(shuō)明被否認(rèn)了,否認(rèn)的voter數(shù)加1	
			case AccessDecisionVoter.ACCESS_DENIED:
				deny++;
				break;
			// 如果是 -1 或者說(shuō)其他的話,就表示棄權(quán),不產(chǎn)于投票	
			default:
				break;
			}
		}
		// 到這的話如果deny大于0的話說(shuō)明被否認(rèn)了
		// 授權(quán)沒(méi)通過(guò),拋出異常
		if (deny > 0) {
			throw new AccessDeniedException(
					this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
		}
		// To get this far, every AccessDecisionVoter abstained
		checkAllowIfAllAbstainDecisions();
	}

對(duì)授權(quán)源碼分析后的總結(jié):

  1. 先是被 FilterSecurityInterceptor 攔截,調(diào)用 doFilter 方法,doFilter 中調(diào)用了其自身實(shí)現(xiàn)的invoke 方法。
  2. 在 invoke 方法中,調(diào)用了父類 AbstractSecurityInterceptor 的 beforeInvocation 方法進(jìn)行;
  3. 在 beforeInvocation 方法中,調(diào)用了 attemptAuthorization 方法進(jìn)行授權(quán)操作;
  4. 在 attemptAuthorization 方法中,使用 AccessDecisionManager 決策對(duì)象調(diào)用 decide 方法進(jìn)行決策,即授權(quán)。
  5. 在 decide 方法中,即是遍歷 AccessDecisionVoter 對(duì)象調(diào)用 vote 方法進(jìn)行投票,判斷是否授權(quán)成功(這里與 AuthenticationManager 中的 authenticate 方法遍歷 AuthenticationProvider 對(duì)象進(jìn)行認(rèn)證類似)。與上圖對(duì)應(yīng)。

SecurityMetadataSource 分析

在 FilterSecurityInterceptor 中有個(gè) FilterInvocationSecurityMetadataSource 類型的屬性對(duì)象,它可以通過(guò) setter 方式進(jìn)行注入的。FilterInvocationSecurityMetadataSource 中沒(méi)有方法,繼承了 SecurityMetadataSource,Spring Security 對(duì)其的默認(rèn)實(shí)現(xiàn)是 DefaultFilterInvocationSecurityMetadataSource。

下面是默認(rèn)實(shí)現(xiàn)的結(jié)構(gòu)圖

【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理
DefaultFilterInvocationSecurityMetadataSource 中的 getAttributes 方法源碼分析如下:

	private final Map<RequestMatcher, Collection<ConfigAttribute>> requestMap;
	// 構(gòu)造注入 路徑 <=> 權(quán)限集 映射
	// requestMap 為 LinkedHashMap 的對(duì)象
	public DefaultFilterInvocationSecurityMetadataSource(
			LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap) {
		this.requestMap = requestMap;
	}
	
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) {
		// 注意 object instanceOf FilterInvocation 為 true
		final HttpServletRequest request = ((FilterInvocation) object).getRequest();
		// 遍歷 requestMap,匹配請(qǐng)求路徑一致的權(quán)限集
		for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : this.requestMap.entrySet()) {
			if (entry.getKey().matches(request)) {
				return entry.getValue();
			}
		}
		return null;
	}

三、自定義 FilterSecurityMetadataSource 對(duì)象(實(shí)戰(zhàn))

配置 SecurityFilterChain 時(shí),使用代碼的方式配置 URL 攔截規(guī)則 和 請(qǐng)求 URL 所需要的權(quán)限,這種方式比較死板,如果想要調(diào)整訪問(wèn)某一個(gè) URL 所需要的權(quán)限,就需要修改代碼。

動(dòng)態(tài)管理權(quán)限規(guī)則就是我們將 URL 攔截規(guī)則和訪問(wèn) URI 所需要的權(quán)限都保存在數(shù)據(jù)庫(kù)中,這樣,在不修改源代碼的情況下,只需要修改數(shù)據(jù)庫(kù)中的數(shù)據(jù),就可以對(duì)權(quán)限進(jìn)行調(diào)整。即不用去修改代碼,達(dá)到了解耦的效果。

當(dāng) URL 和角色進(jìn)行匹配的時(shí)候,Spring Security 是默認(rèn)采用“或者”(OR)的方式來(lái)匹配用戶所擁有的角色。比如:/hello 需要 ROLE_ADMIN、ROLE_USER 角色即可訪問(wèn),即當(dāng)用戶擁有倆個(gè)角色的其中一個(gè)就可以訪問(wèn)。

自定義表

用戶表(user)- 非 RememberMe 持久化那個(gè) persistent_logins 表
【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理角色表(role)
【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理用戶角色關(guān)聯(lián)表 user -> role(user_role)
【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理菜單表(menu)請(qǐng)求路徑
【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理菜單可被什么角色訪問(wèn),即菜單關(guān)聯(lián)角色表(menu_role)
【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理

CustomSecurityMetadataSource

CustomSecurityMetadataSource 是小編自定義的 FilterSecurityMetadataSource 的實(shí)現(xiàn)類,根據(jù)上面的源碼分析,如獲取路徑的匹配權(quán)限需要自己設(shè)定的話,需要自定義SecurityMetadataSource中的getAttribute方法。

CustomSecurityMetadataSource

@Component
public class CustomSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {


    private final MenuService menuService;

    public CustomSecurityMetadataSource(@Autowired MenuService menuService){
        this.menuService = menuService;
    }

    AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        HttpServletRequest request = (HttpServletRequest) ((FilterInvocation) object).getRequest();
        String requestURI = request.getRequestURI();
        // 查詢所有菜單
        List<Menu> menus = menuService.getMenus();
        // 遍歷菜單
        for (Menu menu : menus) {
            if(antPathMatcher.match(menu.getPattern(),requestURI)){
                String[] roles = menu.getRoles().stream().map(Role::getName).toArray(String[]::new);
                // 將 roles 轉(zhuǎn)化成 List<ConfigAttribute) 對(duì)象
                return SecurityConfig.createList(roles);
            }
        }
        return null;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}

配置自定義的 SecurityMetadataSource

SecurityConfig 配置類

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    @Resource
    private MyUserDetailService myUserDetailService;

    private final CustomSecurityMetadataSource customSecurityMetadataSource;

    @Autowired
    public SecurityConfig(CustomSecurityMetadataSource securityMetadataSource){
        this.customSecurityMetadataSource = securityMetadataSource;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        // 1. 獲取工廠對(duì)象
        ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
        // 2. 設(shè)置自定義 url 權(quán)限處理
        http.apply(new UrlAuthorizationConfigurer<>(applicationContext))
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>(){

                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {
                        object.setSecurityMetadataSource(customSecurityMetadataSource);
                        // 是否拒絕公共資源的訪問(wèn)
                        object.setRejectPublicInvocations(false);
                        return object;
                    }
                }
                );

        return http
                .formLogin()
                .and()
                .csrf()
                .disable().build();
    }

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(myUserDetailService)
                .and()
                .build();
    }

}

測(cè)試代碼

測(cè)試 Controller 如下(Service、Dao、entity 類代碼都沒(méi)給出來(lái),如果需要該測(cè)試工程代碼,可以私聊,博客不好全部寫(xiě)出)

@RestController
public class HelloController {

    @GetMapping("/admin/hello")
    public String admin(){
        return "Hello admin!";
    }

    @GetMapping("/user/hello")
    public String user(){
        return "Hello user!";
    }

    @GetMapping("/guest/hello")
    public String guest(){
        return "Hello Guest!";
    }

    @GetMapping("/hello")
    public String hello(){
        return "Hello!";
    }

}

測(cè)試效果

拿 user/123 進(jìn)行測(cè)試,從數(shù)據(jù)庫(kù)表中可以得知,user 用戶只有 ROLE_USER 角色,只能訪問(wèn) /user/** 和 /guest/** 的資源。

測(cè)試效果:

【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理
效果解釋:user 用戶只有 ROLE_USER 角色,可以訪問(wèn) /user/** 資源,也可以訪問(wèn) /guest/** ,這是原因 Spring Security默認(rèn)的匹配規(guī)則是 OR,訪問(wèn) /guest/** 只要有 ROLE_GUEST 或 ROLE_USER 即可。而不能訪問(wèn) /admin/** ,因?yàn)樵撜?qǐng)求需要 ROLE_ADMIN 角色。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-496018.html

四、總結(jié)

  • 三大組件:ConfigAttribute(角色的封裝體)、AccessDecisionManager(決策管理者,調(diào)用 decide 方法進(jìn)行決策)、AccessDecisionVoter(決策者,通過(guò) vote 方法進(jìn)行投票決策)。
  • 請(qǐng)求授權(quán)流程概述:被 FilterSecurityInterceptor 攔截-》調(diào)用invoke方法-》調(diào)用父類 AbstractSecurityInterceptorbeforeInvocation 方法-》通過(guò) FilterSecurityMetadataSource 對(duì)象調(diào)用 getAttribute 得知訪問(wèn)該路徑可被哪些權(quán)限訪問(wèn)-》將其作為參數(shù)調(diào)用 attemptAuthorization 進(jìn)行嘗試授權(quán)-》通過(guò) AccessDecisionManager 做出決策,做決策者是 AccessDecisionVoter,遍歷決策者得出決策結(jié)果。
  • AccessDecisionManager 和 AccessDecisionVoter 之間的關(guān)系,類似于前期說(shuō)的認(rèn)證中的 AuthenticationManager 和 AuthenticationProvider。
  • 自定義持久化URL權(quán)限管理時(shí),需要自定義 FilterSecurityMetadataSource 實(shí)現(xiàn)類,實(shí)現(xiàn) getAttribute 方法(在該方法中從數(shù)據(jù)庫(kù)中獲取對(duì)應(yīng) URL 匹配的角色),然后進(jìn)行配置。

到了這里,關(guān)于【深入淺出 Spring Security(十一)】授權(quán)原理分析和持久化URL權(quán)限管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【深入淺出Spring Security(五)】自定義過(guò)濾器進(jìn)行前后端登錄認(rèn)證

    【深入淺出Spring Security(五)】自定義過(guò)濾器進(jìn)行前后端登錄認(rèn)證

    在【深入淺出Spring Security(二)】Spring Security的實(shí)現(xiàn)原理 中小編闡述了默認(rèn)加載的過(guò)濾器,里面有些過(guò)濾器有時(shí)并不能滿足開(kāi)發(fā)中的實(shí)際需求,這個(gè)時(shí)候就需要我們自定義過(guò)濾器,然后填入或者替換掉原先存在的過(guò)濾器。 首先闡述一下添加過(guò)濾器的四個(gè)方法(都是 HttpSecur

    2024年02月08日
    瀏覽(24)
  • 【深入淺出 Spring Security(十三)】使用 JWT 進(jìn)行前后端分離認(rèn)證(附源碼)

    【深入淺出 Spring Security(十三)】使用 JWT 進(jìn)行前后端分離認(rèn)證(附源碼)

    JWT 全稱 Java web Token,在此所講述的是 JWT 用于身份認(rèn)證,用服務(wù)器端生成的JWT去替代原始的Session認(rèn)證,以提高安全性。 JWT本質(zhì)是一個(gè)Token令牌,是由三部分組成的字符串,分別是頭部(header)、載荷(payload)和簽名(signature)。頭部一般包含該 JWT 的基本信息,例如所使用的

    2024年02月12日
    瀏覽(25)
  • 【深入淺出 Spring Security(四)】登錄用戶數(shù)據(jù)的獲取,超詳細(xì)的源碼分析

    【深入淺出 Spring Security(四)】登錄用戶數(shù)據(jù)的獲取,超詳細(xì)的源碼分析

    在【深入淺出Spring Security(一)】Spring Security的整體架構(gòu) 中敘述過(guò)一個(gè)SecurityContextHolder 這個(gè)類。說(shuō)在處理請(qǐng)求時(shí),Spring Security 會(huì)先從 Session 中取出用戶登錄數(shù)據(jù),保存到 SecurityContextHolder 中,然后在請(qǐng)求處理完畢后,又會(huì)拿 SecurityContextHolder 中的數(shù)據(jù)保存到 Session 中,然后再

    2024年02月07日
    瀏覽(18)
  • 【深入淺出Spring原理及實(shí)戰(zhàn)】「源碼調(diào)試分析」深入源碼探索Spring底層框架的的refresh方法所出現(xiàn)的問(wèn)題和異常

    閱讀Spring官方文檔,了解Spring框架的基本概念和使用方法。 下載Spring源碼,可以從官網(wǎng)或者GitHub上獲取。 閱讀Spring源碼的入口類,了解Spring框架的啟動(dòng)過(guò)程和核心組件的加載順序。 閱讀Spring源碼中的注釋和文檔,了解每個(gè)類和方法的作用和用法。 調(diào)試Spring源碼,可以通過(guò)

    2023年04月23日
    瀏覽(33)
  • 深入淺出Java多線程(十一):AQS

    深入淺出Java多線程(十一):AQS

    大家好,我是你們的老伙計(jì)秀才!今天帶來(lái)的是[深入淺出Java多線程]系列的第十一篇內(nèi)容:AQS( AbstractQueuedSynchronizer )。大家覺(jué)得有用請(qǐng)點(diǎn)贊,喜歡請(qǐng)關(guān)注!秀才在此謝過(guò)大家了?。?! 在現(xiàn)代多核CPU環(huán)境中,多線程編程已成為提升系統(tǒng)性能和并發(fā)處理能力的關(guān)鍵手段。然而

    2024年03月12日
    瀏覽(30)
  • 【深入淺出Spring原理及實(shí)戰(zhàn)】「夯實(shí)基礎(chǔ)系列」360全方位滲透和探究Spring的核心注解開(kāi)發(fā)和實(shí)現(xiàn)指南(Spring5的常見(jiàn)的注解)

    【深入淺出Spring原理及實(shí)戰(zhàn)】「夯實(shí)基礎(chǔ)系列」360全方位滲透和探究Spring的核心注解開(kāi)發(fā)和實(shí)現(xiàn)指南(Spring5的常見(jiàn)的注解)

    Spring 5.x中常見(jiàn)的注解包括@Controller、@Service、@Repository。當(dāng)我們研究Spring Boot源碼時(shí),會(huì)發(fā)現(xiàn)實(shí)際上提供了更多的注解。了解這些注解對(duì)于我們非常重要,盡管目前可能還用不到它們。 注解 功能 @Bean 器中注冊(cè)組件,代替來(lái)的標(biāo)簽 @Configuration 聲明這是一個(gè)配置類,替換以前的配

    2024年02月16日
    瀏覽(21)
  • 深入淺出Spring AOP

    深入淺出Spring AOP

    第1章:引言 大家好,我是小黑,咱們今天要聊的是Java中Spring框架的AOP(面向切面編程)。對(duì)于程序員來(lái)說(shuō),理解AOP對(duì)于掌握Spring框架來(lái)說(shuō)是超級(jí)關(guān)鍵的。它像是魔法一樣,能讓咱們?cè)诓桓淖冊(cè)写a的情況下,給程序增加各種功能。 AOP不僅僅是一個(gè)編程范式,它更是一種思

    2024年01月20日
    瀏覽(28)
  • 論文解讀:Bert原理深入淺出

    摘取于https://www.jianshu.com/p/810ca25c4502 任務(wù)1:Masked Language Model Maked LM 是為了解決單向信息問(wèn)題,現(xiàn)有的語(yǔ)言模型的問(wèn)題在于,沒(méi)有同時(shí)利用雙向信息,如 ELMO 號(hào)稱是雙向LM,但實(shí)際上是兩個(gè)單向 RNN 構(gòu)成的語(yǔ)言模型的拼接,由于時(shí)間序列的關(guān)系,RNN模型預(yù)測(cè)當(dāng)前詞只依賴前面出

    2024年02月11日
    瀏覽(20)
  • 深入淺出:Zookeeper的原理與實(shí)踐

    在當(dāng)今的信息時(shí)代,分布式系統(tǒng)的應(yīng)用越來(lái)越廣泛,而其中一個(gè)至關(guān)重要的組成部分就是Zookeeper。作為一個(gè)分布式協(xié)調(diào)服務(wù),Zookeeper在保障分布式系統(tǒng)的一致性、可靠性和可用性方面發(fā)揮著不可替代的作用。本博客旨在深入淺出地探討Zookeeper的原理與實(shí)踐,幫助讀者全面理解

    2024年04月11日
    瀏覽(27)
  • 深入淺出Java中參數(shù)傳遞的原理

    深入淺出Java中參數(shù)傳遞的原理

    今天,想和大家聊聊關(guān)于java中的參數(shù)傳遞的原理,參數(shù)的傳遞有兩種,值傳遞和引用傳遞。 值傳遞 :是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)復(fù)制一份傳遞到函數(shù)中,這樣在函數(shù)中如果對(duì)參數(shù)進(jìn)行修改,將不會(huì)影響到實(shí)際參數(shù)。 引用傳遞 :是指在調(diào)用函數(shù)時(shí)將實(shí)際參數(shù)的地址傳遞到

    2024年02月01日
    瀏覽(18)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包