最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Security權(quán)限管理實現(xiàn)接口動態(tài)權(quán)限控制

 更新時間:2022年06月20日 10:22:34   作者:MacroZheng  
這篇文章主要為大家介紹了Spring?Security權(quán)限管理實現(xiàn)接口動態(tài)權(quán)限控制,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

SpringBoot實戰(zhàn)電商項目mall(30k+star)地址:https://github.com/macrozheng/mall

摘要

權(quán)限控管理作為后臺管理系統(tǒng)中必要的功能,mall項目中結(jié)合Spring Security實現(xiàn)了基于路徑的動態(tài)權(quán)限控制,可以對后臺接口訪問進(jìn)行細(xì)粒度的控制,今天我們來講下它的后端實現(xiàn)原理。

前置知識

學(xué)習(xí)本文需要一些Spring Security的知識,對Spring Security不太了解的朋友可以看下以下文章。

數(shù)據(jù)庫設(shè)計

權(quán)限管理相關(guān)表已經(jīng)重新設(shè)計,將原來的權(quán)限拆分成了菜單和資源,菜單管理用于控制前端菜單的顯示和隱藏,資源管理用來控制后端接口的訪問權(quán)限。

數(shù)據(jù)庫表結(jié)構(gòu)

其中ums_adminums_role、ums_admin_role_relation為原來的表,其他均為新增表。

數(shù)據(jù)庫表介紹

接下來我們將對每張表的用途做個詳細(xì)介紹。

ums_admin

后臺用戶表,定義了后臺用戶的一些基本信息。

create table ums_admin
(
   id                   bigint not null auto_increment,
   username             varchar(64) comment '用戶名',
   password             varchar(64) comment '密碼',
   icon                 varchar(500) comment '頭像',
   email                varchar(100) comment '郵箱',
   nick_name            varchar(200) comment '昵稱',
   note                 varchar(500) comment '備注信息',
   create_time          datetime comment '創(chuàng)建時間',
   login_time           datetime comment '最后登錄時間',
   status               int(1) default 1 comment '帳號啟用狀態(tài):0->禁用;1->啟用',
   primary key (id)
);

ums_role

后臺用戶角色表,定義了后臺用戶角色的一些基本信息,通過給后臺用戶分配角色來實現(xiàn)菜單和資源的分配。

create table ums_role
(
   id                   bigint not null auto_increment,
   name                 varchar(100) comment '名稱',
   description          varchar(500) comment '描述',
   admin_count          int comment '后臺用戶數(shù)量',
   create_time          datetime comment '創(chuàng)建時間',
   status               int(1) default 1 comment '啟用狀態(tài):0->禁用;1->啟用',
   sort                 int default 0,
   primary key (id)
);

ums_admin_role_relation

后臺用戶和角色關(guān)系表,多對多關(guān)系表,一個角色可以分配給多個用戶。

create table ums_admin_role_relation
(
   id                   bigint not null auto_increment,
   admin_id             bigint,
   role_id              bigint,
   primary key (id)
);

ums_menu

后臺菜單表,用于控制后臺用戶可以訪問的菜單,支持隱藏、排序和更改名稱、圖標(biāo)。

create table ums_menu
(
   id                   bigint not null auto_increment,
   parent_id            bigint comment '父級ID',
   create_time          datetime comment '創(chuàng)建時間',
   title                varchar(100) comment '菜單名稱',
   level                int(4) comment '菜單級數(shù)',
   sort                 int(4) comment '菜單排序',
   name                 varchar(100) comment '前端名稱',
   icon                 varchar(200) comment '前端圖標(biāo)',
   hidden               int(1) comment '前端隱藏',
   primary key (id)
);

ums_resource

后臺資源表,用于控制后臺用戶可以訪問的接口,使用了Ant路徑的匹配規(guī)則,可以使用通配符定義一系列接口的權(quán)限。

create table ums_resource
(
   id                   bigint not null auto_increment,
   category_id          bigint comment '資源分類ID',
   create_time          datetime comment '創(chuàng)建時間',
   name                 varchar(200) comment '資源名稱',
   url                  varchar(200) comment '資源URL',
   description          varchar(500) comment '描述',
   primary key (id)
);

ums_resource_category

后臺資源分類表,在細(xì)粒度進(jìn)行權(quán)限控制時,可能資源會比較多,所以設(shè)計了個資源分類的概念,便于給角色分配資源。

create table ums_resource_category
(
   id                   bigint not null auto_increment,
   create_time          datetime comment '創(chuàng)建時間',
   name                 varchar(200) comment '分類名稱',
   sort                 int(4) comment '排序',
   primary key (id)
);

ums_role_menu_relation

后臺角色菜單關(guān)系表,多對多關(guān)系,可以給一個角色分配多個菜單。

create table ums_role_menu_relation
(
   id                   bigint not null auto_increment,
   role_id              bigint comment '角色I(xiàn)D',
   menu_id              bigint comment '菜單ID',
   primary key (id)
);

ums_role_resource_relation

后臺角色資源關(guān)系表,多對多關(guān)系,可以給一個角色分配多個資源。

create table ums_role_resource_relation
(
   id                   bigint not null auto_increment,
   role_id              bigint comment '角色I(xiàn)D',
   resource_id          bigint comment '資源ID',
   primary key (id)
);

結(jié)合Spring Security實現(xiàn)

實現(xiàn)動態(tài)權(quán)限是在原mall-security模塊的基礎(chǔ)上進(jìn)行改造完成的,原實現(xiàn)有不清楚的可以自行參照前置知識中的文檔來學(xué)習(xí)。

以前的權(quán)限控制

以前的權(quán)限控制是采用Spring Security的默認(rèn)機(jī)制實現(xiàn)的,下面我們以商品模塊的代碼為例來講講實現(xiàn)原理。

首先我們在需要權(quán)限的接口上使用@PreAuthorize注解定義好需要的權(quán)限;

/**
 * 商品管理Controller
 * Created by macro on 2018/4/26.
 */
@Controller
@Api(tags = "PmsProductController", description = "商品管理")
@RequestMapping("/product")
public class PmsProductController {
    @Autowired
    private PmsProductService productService;
    @ApiOperation("創(chuàng)建商品")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    @PreAuthorize("hasAuthority('pms:product:create')")
    public CommonResult create(@RequestBody PmsProductParam productParam, BindingResult bindingResult) {
        int count = productService.create(productParam);
        if (count > 0) {
            return CommonResult.success(count);
        } else {
            return CommonResult.failed();
        }
    }
}

然后將該權(quán)限值存入到權(quán)限表中,當(dāng)用戶登錄時,將其所擁有的權(quán)限查詢出來;

/**
 * UmsAdminService實現(xiàn)類
 * Created by macro on 2018/4/26.
 */
@Service
public class UmsAdminServiceImpl implements UmsAdminService {
    @Override
    public UserDetails loadUserByUsername(String username){
        //獲取用戶信息
        UmsAdmin admin = getAdminByUsername(username);
        if (admin != null) {
            List<UmsPermission> permissionList = getPermissionList(admin.getId());
            return new AdminUserDetails(admin,permissionList);
        }
        throw new UsernameNotFoundException("用戶名或密碼錯誤");
    }
}

之后Spring Security把用戶擁有的權(quán)限值和接口上注解定義的權(quán)限值進(jìn)行比對,如果包含則可以訪問,反之就不可以訪問;

但是這樣做會帶來一些問題,我們需要在每個接口上都定義好訪問該接口的權(quán)限值,而且只能挨個控制接口的權(quán)限,無法批量控制。其實每個接口都可以由它的訪問路徑唯一確定,我們可以使用基于路徑的動態(tài)權(quán)限控制來解決這些問題。

基于路徑的動態(tài)權(quán)限控制

接下來我們詳細(xì)介紹下如何使用Spring Security實現(xiàn)基于路徑的動態(tài)權(quán)限。

首先我們需要創(chuàng)建一個過濾器,用于實現(xiàn)動態(tài)權(quán)限控制,這里需要注意的是doFilter方法,對于OPTIONS請求直接放行,否則前端調(diào)用會出現(xiàn)跨域問題。對于配置在IgnoreUrlsConfig中的白名單路徑我也需要直接放行,所有的鑒權(quán)操作都會在super.beforeInvocation(fi)中進(jìn)行。

/**
 * 動態(tài)權(quán)限過濾器,用于實現(xiàn)基于路徑的動態(tài)權(quán)限過濾
 * Created by macro on 2020/2/7.
 */
public class DynamicSecurityFilter extends AbstractSecurityInterceptor implements Filter {
    @Autowired
    private DynamicSecurityMetadataSource dynamicSecurityMetadataSource;
    @Autowired
    private IgnoreUrlsConfig ignoreUrlsConfig;
    @Autowired
    public void setMyAccessDecisionManager(DynamicAccessDecisionManager dynamicAccessDecisionManager) {
        super.setAccessDecisionManager(dynamicAccessDecisionManager);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain);
        //OPTIONS請求直接放行
        if(request.getMethod().equals(HttpMethod.OPTIONS.toString())){
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
            return;
        }
        //白名單請求直接放行
        PathMatcher pathMatcher = new AntPathMatcher();
        for (String path : ignoreUrlsConfig.getUrls()) {
            if(pathMatcher.match(path,request.getRequestURI())){
                fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
                return;
            }
        }
        //此處會調(diào)用AccessDecisionManager中的decide方法進(jìn)行鑒權(quán)操作
        InterceptorStatusToken token = super.beforeInvocation(fi);
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        } finally {
            super.afterInvocation(token, null);
        }
    }
    @Override
    public void destroy() {
    }
    @Override
    public Class<?> getSecureObjectClass() {
        return FilterInvocation.class;
    }
    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return dynamicSecurityMetadataSource;
    }
}

在DynamicSecurityFilter中調(diào)用super.beforeInvocation(fi)方法時會調(diào)用AccessDecisionManager中的decide方法用于鑒權(quán)操作,而decide方法中的configAttributes參數(shù)會通過SecurityMetadataSource中的getAttributes方法來獲取,configAttributes其實就是配置好的訪問當(dāng)前接口所需要的權(quán)限,下面是簡化版的beforeInvocation源碼。

public abstract class AbstractSecurityInterceptor implements InitializingBean,
		ApplicationEventPublisherAware, MessageSourceAware {
protected InterceptorStatusToken beforeInvocation(Object object) {
        //獲取元數(shù)據(jù)
		Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource()
				.getAttributes(object);
		Authentication authenticated = authenticateIfRequired();
		//進(jìn)行鑒權(quán)操作
		try {
			this.accessDecisionManager.decide(authenticated, object, attributes);
		}
		catch (AccessDeniedException accessDeniedException) {
			publishEvent(new AuthorizationFailureEvent(object, attributes, authenticated,
					accessDeniedException));
			throw accessDeniedException;
		}
	}
}

知道了鑒權(quán)的原理,接下來我們需要自己實現(xiàn)SecurityMetadataSource接口的getAttributes方法,用于獲取當(dāng)前訪問路徑所需資源。

/**
 * 動態(tài)權(quán)限數(shù)據(jù)源,用于獲取動態(tài)權(quán)限規(guī)則
 * Created by macro on 2020/2/7.
 */
public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    private static Map<String, ConfigAttribute> configAttributeMap = null;
    @Autowired
    private DynamicSecurityService dynamicSecurityService;
    @PostConstruct
    public void loadDataSource() {
        configAttributeMap = dynamicSecurityService.loadDataSource();
    }
    public void clearDataSource() {
        configAttributeMap.clear();
        configAttributeMap = null;
    }
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        if (configAttributeMap == null) this.loadDataSource();
        List<ConfigAttribute>  configAttributes = new ArrayList<>();
        //獲取當(dāng)前訪問的路徑
        String url = ((FilterInvocation) o).getRequestUrl();
        String path = URLUtil.getPath(url);
        PathMatcher pathMatcher = new AntPathMatcher();
        Iterator<String> iterator = configAttributeMap.keySet().iterator();
        //獲取訪問該路徑所需資源
        while (iterator.hasNext()) {
            String pattern = iterator.next();
            if (pathMatcher.match(pattern, path)) {
                configAttributes.add(configAttributeMap.get(pattern));
            }
        }
        // 未設(shè)置操作請求權(quán)限,返回空集合
        return configAttributes;
    }
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }
    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}

由于我們的后臺資源規(guī)則被緩存在了一個Map對象之中,所以當(dāng)后臺資源發(fā)生變化時,我們需要清空緩存的數(shù)據(jù),然后下次查詢時就會被重新加載進(jìn)來。

這里我們需要修改UmsResourceController類,注入DynamicSecurityMetadataSource,當(dāng)修改后臺資源時,需要調(diào)用clearDataSource方法來清空緩存的數(shù)據(jù)。

/**
 * 后臺資源管理Controller
 * Created by macro on 2020/2/4.
 */
@Controller
@Api(tags = "UmsResourceController", description = "后臺資源管理")
@RequestMapping("/resource")
public class UmsResourceController {
    @Autowired
    private UmsResourceService resourceService;
    @Autowired
    private DynamicSecurityMetadataSource dynamicSecurityMetadataSource;
    @ApiOperation("添加后臺資源")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult create(@RequestBody UmsResource umsResource) {
        int count = resourceService.create(umsResource);
        dynamicSecurityMetadataSource.clearDataSource();
        if (count &gt; 0) {
            return CommonResult.success(count);
        } else {
            return CommonResult.failed();
        }
    }
 }

之后我們需要實現(xiàn)AccessDecisionManager接口來實現(xiàn)權(quán)限校驗,對于沒有配置資源的接口我們直接允許訪問,對于配置了資源的接口,我們把訪問所需資源和用戶擁有的資源進(jìn)行比對,如果匹配則允許訪問。

/**
 * 動態(tài)權(quán)限決策管理器,用于判斷用戶是否有訪問權(quán)限
 * Created by macro on 2020/2/7.
 */
public class DynamicAccessDecisionManager implements AccessDecisionManager {
    @Override
    public void decide(Authentication authentication, Object object,
                       Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        // 當(dāng)接口未被配置資源時直接放行
        if (CollUtil.isEmpty(configAttributes)) {
            return;
        }
        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
        while (iterator.hasNext()) {
            ConfigAttribute configAttribute = iterator.next();
            //將訪問所需資源或用戶擁有資源進(jìn)行比對
            String needAuthority = configAttribute.getAttribute();
            for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
                if (needAuthority.trim().equals(grantedAuthority.getAuthority())) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("抱歉,您沒有訪問權(quán)限");
    }
    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }
    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}

我們之前在DynamicSecurityMetadataSource中注入了一個DynamicSecurityService對象,它是我自定義的一個動態(tài)權(quán)限業(yè)務(wù)接口,其主要用于加載所有的后臺資源規(guī)則。

/**
 * 動態(tài)權(quán)限相關(guān)業(yè)務(wù)類
 * Created by macro on 2020/2/7.
 */
public interface DynamicSecurityService {
    /**
     * 加載資源ANT通配符和資源對應(yīng)MAP
     */
    Map<String, ConfigAttribute> loadDataSource();
}

接下來我們需要修改Spring Security的配置類SecurityConfig,當(dāng)有動態(tài)權(quán)限業(yè)務(wù)類時在FilterSecurityInterceptor過濾器前添加我們的動態(tài)權(quán)限過濾器。

這里在創(chuàng)建動態(tài)權(quán)限相關(guān)對象時,還使用了@ConditionalOnBean這個注解,當(dāng)沒有動態(tài)權(quán)限業(yè)務(wù)類時就不會創(chuàng)建動態(tài)權(quán)限相關(guān)對象,實現(xiàn)了有動態(tài)權(quán)限控制和沒有這兩種情況的兼容。

/**
 * 對SpringSecurity的配置的擴(kuò)展,支持自定義白名單資源路徑和查詢用戶邏輯
 * Created by macro on 2019/11/5.
 */
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired(required = false)
    private DynamicSecurityService dynamicSecurityService;
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity
                .authorizeRequests();
        //有動態(tài)權(quán)限配置時添加動態(tài)權(quán)限校驗過濾器
        if(dynamicSecurityService!=null){
            registry.and().addFilterBefore(dynamicSecurityFilter(), FilterSecurityInterceptor.class);
        }
    }
    @ConditionalOnBean(name = "dynamicSecurityService")
    @Bean
    public DynamicAccessDecisionManager dynamicAccessDecisionManager() {
        return new DynamicAccessDecisionManager();
    }
    @ConditionalOnBean(name = "dynamicSecurityService")
    @Bean
    public DynamicSecurityFilter dynamicSecurityFilter() {
        return new DynamicSecurityFilter();
    }
    @ConditionalOnBean(name = "dynamicSecurityService")
    @Bean
    public DynamicSecurityMetadataSource dynamicSecurityMetadataSource() {
        return new DynamicSecurityMetadataSource();
    }
}

這里還有個問題需要提下,當(dāng)前端跨域訪問沒有權(quán)限的接口時,會出現(xiàn)跨域問題,只需要在沒有權(quán)限訪問的處理類RestfulAccessDeniedHandler中添加允許跨域訪問的響應(yīng)頭即可。

/**
 * 自定義返回結(jié)果:沒有權(quán)限訪問時
 * Created by macro on 2018/4/26.
 */
public class RestfulAccessDeniedHandler implements AccessDeniedHandler{
    @Override
    public void handle(HttpServletRequest request,
                       HttpServletResponse response,
                       AccessDeniedException e) throws IOException, ServletException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Cache-Control","no-cache");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));
        response.getWriter().flush();
    }
}

當(dāng)我們其他模塊需要動態(tài)權(quán)限控制時,只要創(chuàng)建一個DynamicSecurityService對象就行了,比如在mall-admin模塊中我們啟用了動態(tài)權(quán)限功能。

/**
 * mall-security模塊相關(guān)配置
 * Created by macro on 2019/11/9.
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MallSecurityConfig extends SecurityConfig {
    @Autowired
    private UmsAdminService adminService;
    @Autowired
    private UmsResourceService resourceService;
    @Bean
    public UserDetailsService userDetailsService() {
        //獲取登錄用戶信息
        return username -&gt; adminService.loadUserByUsername(username);
    }
    @Bean
    public DynamicSecurityService dynamicSecurityService() {
        return new DynamicSecurityService() {
            @Override
            public Map&lt;String, ConfigAttribute&gt; loadDataSource() {
                Map&lt;String, ConfigAttribute&gt; map = new ConcurrentHashMap&lt;&gt;();
                List&lt;UmsResource&gt; resourceList = resourceService.listAll();
                for (UmsResource resource : resourceList) {
                    map.put(resource.getUrl(), new org.springframework.security.access.SecurityConfig(resource.getId() + ":" + resource.getName()));
                }
                return map;
            }
        };
    }
}

權(quán)限管理功能演示

具體參考:大家心心念念的權(quán)限管理功能,這次安排上了!

mall項目更新源碼地址 https://github.com/macrozheng/mall

以上就是Spring Security權(quán)限管理實現(xiàn)接口動態(tài)權(quán)限控制的詳細(xì)內(nèi)容,更多關(guān)于Spring Security接口動態(tài)權(quán)限控制的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JAVA?流程控制專項精講

    JAVA?流程控制專項精講

    不喜歡羅里吧嗦,講的很精簡易懂。從基礎(chǔ)開始講,后續(xù)會講到JAVA高級,中間會穿插面試題和項目實戰(zhàn),希望能給大家?guī)韼椭?/div> 2022-03-03
  • 深入了解SpringMVC初始化流程

    深入了解SpringMVC初始化流程

    框架源碼是我們?Coding?晉級中的必修課,SSM?應(yīng)該算是小伙伴們?nèi)粘=佑|最多的框架了,這其中?SpringMVC?初始化流程相對來說要簡單一些,因此本文就先來和大家分析一下?SpringMVC?初始化流程
    2022-07-07
  • Java中的==使用方法詳解

    Java中的==使用方法詳解

    這篇文章主要給大家介紹了關(guān)于Java中的==使用方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • 使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長

    使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長

    這篇文章主要介紹了使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java實現(xiàn)矩陣乘法以及優(yōu)化的方法實例

    Java實現(xiàn)矩陣乘法以及優(yōu)化的方法實例

    這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)矩陣乘法以及優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI)

    淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI)

    這篇文章主要介紹了淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • Spring定時任務(wù)實現(xiàn)與配置(一)

    Spring定時任務(wù)實現(xiàn)與配置(一)

    這篇文章主要為大家詳細(xì)介紹了Spring定時任務(wù)的實現(xiàn)與配置第一篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Spring Boot數(shù)據(jù)庫鏈接池配置方法

    Spring Boot數(shù)據(jù)庫鏈接池配置方法

    這篇文章主要介紹了Spring Boot數(shù)據(jù)庫鏈接池配置方法,需要的朋友可以參考下
    2017-04-04
  • SpringBoot動態(tài)Feign服務(wù)調(diào)用詳解

    SpringBoot動態(tài)Feign服務(wù)調(diào)用詳解

    Feign是Netflix公司開發(fā)的一個聲明式的REST調(diào)用客戶端; Ribbon負(fù)載均衡、 Hystrⅸ服務(wù)熔斷是我們Spring Cloud中進(jìn)行微服務(wù)開發(fā)非?;A(chǔ)的組件,在使用的過程中我們也發(fā)現(xiàn)它們一般都是同時出現(xiàn)的,而且配置也都非常相似
    2022-12-12
  • Java Web制作登錄驗證碼實現(xiàn)代碼解析

    Java Web制作登錄驗證碼實現(xiàn)代碼解析

    這篇文章主要介紹了Java Web制作登錄驗證碼實現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09

最新評論

徐州市| 岑巩县| 济源市| 江永县| 积石山| 莱西市| 丹凤县| 宁国市| 古浪县| 宜都市| 白河县| 西乌珠穆沁旗| 淅川县| 酒泉市| 高平市| 乡城县| 务川| 天台县| 漯河市| 浦县| 岑巩县| 平塘县| 巫溪县| 麻栗坡县| 秦皇岛市| 新宁县| 澄江县| 大渡口区| 石嘴山市| 乐亭县| 甘谷县| 通海县| 辰溪县| 海安县| 汾西县| 屏边| 儋州市| 天台县| 迁西县| 澄江县| 广昌县|