1. 程式人生 > >Shiro學習-授權及ini配置

Shiro學習-授權及ini配置

                                              Shrio的授權及ini配置


作者:vashon

時間:2018-03-17


Shiro授權

授權

授權,也叫訪問控制,即在應用中控制誰能訪問哪些資源(如訪問頁面/編輯資料/頁面操作等)。在授權中需瞭解的幾個關鍵物件:主體(Subject)、資源(Resource)、許可權(Permission)、角色(Role)。

主體
主體,即訪問應用的使用者,在 Shiro 中使用 Subject 代表該使用者。使用者只有授權後才允許訪問相應的資源。

資源
在應用中使用者可以訪問的任何東西,比如訪問 JSP 頁面、檢視/編輯某些資料、訪問某個業務方法、列印文字等等都是資源。使用者只要授權後才能訪問。

許可權
安全策略中的原子授權單位,通過許可權我們可以表示在應用中使用者有沒有操作某個資源的權力。即許可權表示在應用中使用者能不能訪問某個資源,如: 訪問使用者列表頁面
檢視/新增/修改/刪除使用者資料(即很多時候都是 CRUD(增查改刪)式許可權控制)
列印文件等等。。。

如上可以看出,許可權代表了使用者有沒有操作某個資源的權利,即反映在某個資源上的操作允不允許,不反映誰去執行這個操作。所以後續還需要把許可權賦予給使用者,即定義哪個使用者允許在某個資源上做什麼操作(許可權),Shiro 不會去做這件事情,而是由實現人員提供。

Shiro 支援粗粒度許可權(如使用者模組的所有許可權)和細粒度許可權(操作某個使用者的許可權,即例項級別的),後續部分介紹。

角色
角色代表了操作集合,可以理解為許可權的集合,一般情況下我們會賦予使用者角色而不是許可權,即這樣使用者可以擁有一組許可權,賦予許可權時比較方便。典型的如:專案經理、技術總監、CTO、開發工程師等都是角色,不同的角色擁有一組不同的許可權。

隱式角色
即直接通過角色來驗證使用者有沒有操作許可權,如在應用中 CTO、技術總監、開發工程師可以使用印表機,假設某天不允許開發工程師使用印表機,此時需要從應用中刪除相應程式碼;再如在應用中 CTO、技術總監可以檢視使用者、檢視許可權;突然有一天不允許技術總監檢視使用者、檢視許可權了,需要在相關程式碼中把技術總監角色從判斷邏輯中刪除掉;即粒度是以角色為單位進行訪問控制的,粒度較粗;如果進行修改可能造成多處程式碼修改。

顯示角色
在程式中通過許可權控制誰能訪問某個資源,角色聚合一組許可權集合;這樣假設哪個角色不能訪問某個資源,只需要從角色代表的許可權集合中移除即可;無須修改多處程式碼;即粒度是以資源/例項為單位的;粒度較細。

請 google 搜尋“RBAC”和“RBAC新解”分別瞭解“基於角色的訪問控制”“基於資源的訪問控制(Resource-Based Access Control)”。

授權方式

Shiro 支援三種方式的授權:

程式設計式:通過寫 if/else 授權程式碼塊完成:

Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
    //有許可權
} else {
    //無許可權
}

註解式:通過在執行的 Java 方法上放置相應的註解完成:

@RequiresRoles("admin")
public void hello() {
    //有許可權
}

沒有許可權將丟擲相應的異常;

JSP/GSP 標籤:在 JSP/GSP 頁面通過相應的標籤完成:

<shiro:hasRole name="admin">
<!— 有許可權 —>
</shiro:hasRole>

後續部分將詳細介紹如何使用。

授權

基於角色的訪問控制(隱式角色)

1、在 ini 配置檔案配置使用者擁有的角色(shiro-role.ini)

[users]
zhang=123,role1,role2
wang=123,role1

規則即:“使用者名稱=密碼,角色1,角色2”,如果需要在應用中判斷使用者是否有相應角色,就需要在相應的 Realm 中返回角色資訊,也就是說 Shiro 不負責維護使用者-角色資訊,需要應用提供,Shiro 只是提供相應的介面方便驗證,後續會介紹如何動態的獲取使用者角色。

2、測試用例(com.github.zhangkaitao.shiro.chapter3.RoleTest)

    @Test
    public void testHasRole() {
        login("classpath:shiro-role.ini", "zhang", "123");
        //判斷擁有角色:role1
        Assert.assertTrue(subject().hasRole("role1"));
        //判斷擁有角色:role1 and role2
        Assert.assertTrue(subject().hasAllRoles(Arrays.asList("role1", "role2")));
        //判斷擁有角色:role1 and role2 and !role3
        boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3"));
        Assert.assertEquals(true, result[0]);
        Assert.assertEquals(true, result[1]);
        Assert.assertEquals(false, result[2]);
    }

Shiro 提供了 hasRole/hasRole 用於判斷使用者是否擁有某個角色/某些許可權;但是沒有提供如 hashAnyRole 用於判斷是否有某些許可權中的某一個。

    @Test(expected = UnauthorizedException.class)
    public void testCheckRole() {
        login("classpath:shiro-role.ini", "zhang", "123");
        //斷言擁有角色:role1
        subject().checkRole("role1");
        //斷言擁有角色:role1 and role3 失敗丟擲異常
        subject().checkRoles("role1", "role3");
    }

Shiro 提供的 checkRole/checkRoles 和 hasRole/hasAllRoles 不同的地方是它在判斷為假的情況下會丟擲 UnauthorizedException 異常。

到此基於角色的訪問控制(即隱式角色)就完成了,這種方式的缺點就是如果很多地方進行了角色判斷,但是有一天不需要了那麼就需要修改相應程式碼把所有相關的地方進行刪除;這就是粗粒度造成的問題。

基於資源的訪問控制(顯示角色)

1、在 ini 配置檔案配置使用者擁有的角色及角色-許可權關係(shiro-permission.ini)

[users]
zhang=123,role1,role2
wang=123,role1
[roles]
role1=user:create,user:update
role2=user:create,user:delete

規則:“使用者名稱=密碼,角色 1,角色 2”“角色=許可權 1,許可權 2”,即首先根據使用者名稱找到角色,然後根據角色再找到許可權;即角色是許可權集合;Shiro 同樣不進行許可權的維護,需要我們通過 Realm 返回相應的許可權資訊。只需要維護“使用者——角色”之間的關係即可。

2、測試用例(com.github.zhangkaitao.shiro.chapter3.PermissionTest)

    @Test
    public void testIsPermitted() {
        login("classpath:shiro-permission.ini", "zhang", "123");
        //判斷擁有許可權:user:create
        Assert.assertTrue(subject().isPermitted("user:create"));
        //判斷擁有許可權:user:update and user:delete
        Assert.assertTrue(subject().isPermittedAll("user:update", "user:delete"));
        //判斷沒有許可權:user:view
        Assert.assertFalse(subject().isPermitted("user:view"));
    }

Shiro 提供了 isPermitted 和 isPermittedAll 用於判斷使用者是否擁有某個許可權或所有許可權,也沒有提供如 isPermittedAny 用於判斷擁有某一個許可權的介面。

    @Test(expected = UnauthorizedException.class)
    public void testCheckPermission () {
        login("classpath:shiro-permission.ini", "zhang", "123");
        //斷言擁有許可權:user:create
        subject().checkPermission("user:create");
        //斷言擁有許可權:user:delete and user:update
        subject().checkPermissions("user:delete", "user:update");
        //斷言擁有許可權:user:view 失敗丟擲異常
        subject().checkPermissions("user:view");
    }&nbsp;

但是失敗的情況下會丟擲 UnauthorizedException 異常。

到此基於資源的訪問控制(顯示角色)就完成了,也可以叫基於許可權的訪問控制,這種方式的一般規則是“資源識別符號:操作”,即是資源級別的粒度;這種方式的好處就是如果要修改基本都是一個資源級別的修改,不會對其他模組程式碼產生影響,粒度小。但是實現起來可能稍微複雜點,需要維護“使用者——角色,角色——許可權(資源:操作)”之間的關係。

Permission

字串萬用字元許可權

規則:“資源識別符號:操作:物件例項 ID” 即對哪個資源的哪個例項可以進行什麼操作。其預設支援萬用字元許可權字串,“:”表示資源/操作/例項的分割;“,”表示操作的分割;“*”表示任意資源/操作/例項。

1、單個資源單個許可權

subject().checkPermissions("system:user:update");

使用者擁有資源“system:user”的“update”許可權。

2、單個資源多個許可權

role41=system:user:update,system:user:delete

然後通過如下程式碼判斷

subject().checkPermissions("system:user:update", "system:user:delete");

使用者擁有資源“system:user”的“update”和“delete”許可權。如上可以簡寫成:

ini 配置(表示角色4擁有 system:user 資源的 update 和 delete 許可權)

role42="system:user:update,delete"

接著可以通過如下程式碼判斷

subject().checkPermissions("system:user:update,delete");

通過“system:user:update,delete”驗證“system:user:update, system:user:delete”是沒問題的,但是反過來是規則不成立。

3、單個資源全部許可權

ini 配置

role51="system:user:create,update,delete,view"

然後通過如下程式碼判斷

subject().checkPermissions("system:user:create,delete,update:view");

使用者擁有資源“system:user”的“create”、“update”、“delete”和“view”所有許可權。如上可以簡寫成:

ini 配置檔案(表示角色 5 擁有 system:user 的所有許可權)

role52=system:user:*

也可以簡寫為(推薦上邊的寫法):

role53=system:user

然後通過如下程式碼判斷

subject().checkPermissions("system:user:*");
subject().checkPermissions("system:user");&nbsp;

通過“system:user:*”驗證“system:user:create,delete,update:view”可以,但是反過來是不成立的。

4、所有資源全部許可權

ini 配置

role61=*:view

然後通過如下程式碼判斷

subject().checkPermissions("user:view");

使用者擁有所有資源的“view”所有許可權。假設判斷的許可權是“"system:user:view”,那麼需要“role5=::view”這樣寫才行

5、例項級別的許可權

  • 單個例項單個許可權

ini 配置

role71=user:view:1

對資源 user 的 1 例項擁有 view 許可權。

然後通過如下程式碼判斷

subject().checkPermissions("user:view:1");

  • 單個例項多個許可權

ini 配置

role72="user:update,delete:1"

對資源 user 的 1 例項擁有 update、delete 許可權。

然後通過如下程式碼判斷

subject().checkPermissions("user:delete,update:1");
subject().checkPermissions("user:update:1", "user:delete:1");&nbsp;
  • 單個例項所有許可權

ini 配置

role73=user:*:1

對資源 user 的 1 例項擁有所有許可權。

然後通過如下程式碼判斷

subject().checkPermissions("user:update:1", "user:delete:1", "user:view:1");

  • 所有例項單個許可權

ini 配置

role74=user:auth:*

對資源 user 的 1 例項擁有所有許可權。

然後通過如下程式碼判斷

subject().checkPermissions("user:auth:1", "user:auth:2");

  • 所有例項所有許可權

ini 配置

role75=user:*:*

對資源 user 的 1 例項擁有所有許可權。

然後通過如下程式碼判斷

subject().checkPermissions("user:view:1", "user:auth:2");

6、Shiro 對許可權字串缺失部分的處理

如“user:view”等價於“user:view:*”;而“organization”等價於“organization:*”或者“organization:*:*”。可以這麼理解,這種方式實現了字首匹配。

另外如“user:*”可以匹配如“user:delete”、“user:delete”可以匹配如“user:delete:1”、“user:*:1”可以匹配如“user:view:1”、“user”可以匹配“user:view”或“user:view:1”等。即*可以匹配所有,不加*可以進行字首匹配;但是如“*:view”不能匹配“system:user:view”,需要使用“*:*:view”,即字尾匹配必須指定字首(多個冒號就需要多個*來匹配)。

7、WildcardPermission

如下兩種方式是等價的:

subject().checkPermission("menu:view:1");
subject().checkPermission(new WildcardPermission("menu:view:1"));&nbsp;

因此沒什麼必要的話使用字串更方便。

8、效能問題

萬用字元匹配方式比字串相等匹配來說是更復雜的,因此需要花費更長時間,但是一般系統的許可權不會太多,且可以配合快取來提供其效能,如果這樣效能還達不到要求我們可以實現位操作演算法實現效能更好的許可權匹配。另外例項級別的許可權驗證如果資料量太大也不建議使用,可能造成查詢許可權及匹配變慢。可以考慮比如在sql查詢時加上許可權字串之類的方式在查詢時就完成了許可權匹配。

授權流程


流程如下:

  1. 首先呼叫 Subject.isPermitted*/hasRole*介面,其會委託給 SecurityManager,而 SecurityManager 接著會委託給 Authorizer;
  2. Authorizer 是真正的授權者,如果我們呼叫如 isPermitted(“user:view”),其首先會通過 PermissionResolver 把字串轉換成相應的 Permission 例項;
  3. 在進行授權之前,其會呼叫相應的 Realm 獲取 Subject 相應的角色/許可權用於匹配傳入的角色/許可權;
  4. Authorizer 會判斷 Realm 的角色/許可權是否和傳入的匹配,如果有多個 Realm,會委託給 ModularRealmAuthorizer 進行迴圈判斷,如果匹配如 isPermitted*/hasRole* 會返回 true,否則返回 false 表示授權失敗。

ModularRealmAuthorizer 進行多 Realm 匹配流程:

  • 首先檢查相應的 Realm 是否實現了實現了 Authorizer;
  • 如果實現了 Authorizer,那麼接著呼叫其相應的 isPermitted*/hasRole* 介面進行匹配;
  • 如果有一個 Realm 匹配那麼將返回 true,否則返回 false。

如果 Realm 進行授權的話,應該繼承 AuthorizingRealm,其流程是:

  • 如果呼叫 hasRole*,則直接獲取 AuthorizationInfo.getRoles() 與傳入的角色比較即可;首先如果呼叫如 isPermitted(“user:view”),首先通過 PermissionResolver 將許可權字串轉換成相應的 Permission 例項,預設使用 WildcardPermissionResolver,即轉換為萬用字元的 WildcardPermission;
  • 通過 AuthorizationInfo.getObjectPermissions() 得到 Permission 例項集合;通過 AuthorizationInfo.getStringPermissions() 得到字串集合並通過 PermissionResolver 解析為 Permission 例項;然後獲取使用者的角色,並通過 RolePermissionResolver 解析角色對應的許可權集合(預設沒有實現,可以自己提供);
  • 接著呼叫 Permission.implies(Permission p) 逐個與傳入的許可權比較,如果有匹配的則返回 true,否則 false。

Authorizer、PermissionResolver及RolePermissionResolver

Authorizer 的職責是進行授權(訪問控制),是 Shiro API 中授權核心的入口點,其提供了相應的角色/許可權判斷介面,具體請參考其 Javadoc。SecurityManager 繼承了 Authorizer 介面,且提供了 ModularRealmAuthorizer 用於多 Realm 時的授權匹配。PermissionResolver 用於解析許可權字串到 Permission 例項,而 RolePermissionResolver 用於根據角色解析相應的許可權集合。

我們可以通過如下 ini 配置更改 Authorizer 實現:

authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
securityManager.authorizer=$authorizer

對於 ModularRealmAuthorizer,相應的 AuthorizingSecurityManager 會在初始化完成後自動將相應的 realm 設定進去,我們也可以通過呼叫其 setRealms() 方法進行設定。對於實現自己的 authorizer 可以參考 ModularRealmAuthorizer 實現即可,在此就不提供示例了。

設定 ModularRealmAuthorizer 的 permissionResolver,其會自動設定到相應的 Realm 上(其實現了 PermissionResolverAware 介面),如:

permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
authorizer.permissionResolver=$permissionResolver

設定 ModularRealmAuthorizer 的 rolePermissionResolver,其會自動設定到相應的 Realm 上(其實現了 RolePermissionResolverAware 介面),如:

rolePermissionResolver=com.github.zhangkaitao.shiro.chapter3.permission.MyRolePermissionResolver
authorizer.rolePermissionResolver=$rolePermissionResolver

示例

1、ini 配置(shiro-authorizer.ini)

[main]
\#自定義authorizer
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
\#自定義permissionResolver
\#permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
permissionResolver=com.github.zhangkaitao.shiro.chapter3.permission.BitAndWildPermissionResolver
authorizer.permissionResolver=$permissionResolver
\#自定義rolePermissionResolver
rolePermissionResolver=com.github.zhangkaitao.shiro.chapter3.permission.MyRolePermissionResolver
authorizer.rolePermissionResolver=$rolePermissionResolver
securityManager.authorizer=$authorizer
\#自定義realm 一定要放在securityManager.authorizer賦值之後(因為呼叫setRealms會將realms設定給authorizer,並給各個Realm設定permissionResolver和rolePermissionResolver)
realm=com.github.zhangkaitao.shiro.chapter3.realm.MyRealm
securityManager.realms=$realm

設定 securityManager 的 realms 一定要放到最後,因為在呼叫 SecurityManager.setRealms 時會將 realms 設定給 authorizer,併為各個 Realm 設定 permissionResolver 和 rolePermissionResolver。另外,不能使用 IniSecurityManagerFactory 建立的 IniRealm,因為其初始化順序的問題可能造成後續的初始化 Permission 造成影響。


2、定義 BitAndWildPermissionResolver 及 BitPermission

BitPermission 用於實現位移方式的許可權,如規則是:

許可權字串格式:+ 資源字串 + 許可權位 + 例項 ID;以 + 開頭中間通過 + 分割;許可權:0 表示所有許可權;1 新增(二進位制:0001)、2 修改(二進位制:0010)、4 刪除(二進位制:0100)、8 檢視(二進位制:1000);如 +user+10 表示對資源 user 擁有修改 / 檢視許可權。

public class BitPermission implements Permission {
    private String resourceIdentify;
    private int permissionBit;
    private String instanceId;
    public BitPermission(String permissionString) {
        String[] array = permissionString.split("\\+");
        if(array.length > 1) {
            resourceIdentify = array[1];
        }
        if(StringUtils.isEmpty(resourceIdentify)) {
            resourceIdentify = "*";
        }
        if(array.length > 2) {
            permissionBit = Integer.valueOf(array[2]);
        }
        if(array.length > 3) {
            instanceId = array[3];
        }
        if(StringUtils.isEmpty(instanceId)) {
            instanceId = "*";
        }
    }
    @Override
    public boolean implies(Permission p) {
        if(!(p instanceof BitPermission)) {
            return false;
        }
        BitPermission other = (BitPermission) p;
        if(!("*".equals(this.resourceIdentify) || this.resourceIdentify.equals(other.resourceIdentify))) {
            return false;
        }
        if(!(this.permissionBit ==0 || (this.permissionBit & other.permissionBit) != 0)) {
            return false;
        }
        if(!("*".equals(this.instanceId) || this.instanceId.equals(other.instanceId))) {
            return false;
        }
        return true;
    }
}

Permission 介面提供了 boolean implies(Permission p) 方法用於判斷許可權匹配的;

public class BitAndWildPermissionResolver implements PermissionResolver {
    @Override
    public Permission resolvePermission(String permissionString) {
        if(permissionString.startsWith("+")) {
            return new BitPermission(permissionString);
        }
        return new WildcardPermission(permissionString);
    }
}&nbsp;

BitAndWildPermissionResolver 實現了 PermissionResolver 介面,並根據許可權字串是否以 “+” 開頭來解析許可權字串為 BitPermission 或 WildcardPermission。


3、定義 MyRolePermissionResolver

RolePermissionResolver 用於根據角色字串來解析得到許可權集合。

public class MyRolePermissionResolver implements RolePermissionResolver {
    @Override
    public Collection<Permission> resolvePermissionsInRole(String roleString) {
        if("role1".equals(roleString)) {
            return Arrays.asList((Permission)new WildcardPermission("menu:*"));
        }
        return null;
    }
}&nbsp;

此處的實現很簡單,如果使用者擁有 role1,那麼就返回一個 “menu:*” 的許可權。

4、自定義 Realm

public class MyRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole("role1");
        authorizationInfo.addRole("role2");
        authorizationInfo.addObjectPermission(new BitPermission("+user1+10"));
        authorizationInfo.addObjectPermission(new WildcardPermission("user1:*"));
        authorizationInfo.addStringPermission("+user2+10");
        authorizationInfo.addStringPermission("user2:*");
        return authorizationInfo;
    }
    @Override
    
            
           

相關推薦

Shiro學習-授權ini配置

                                          &

Apache Shiro學習----配置(與SpringMVC集成)

async 匹配 過濾 -i fig hit http struct 找到 1.web.xml文件中配置 <!--將shiro的配置文件交給Spring監聽器初始化--> <context-param> <param

shiro授權自定義realm授權(七)

qbc mtp jbd red es6 sil llb wmi sin 1.授權流程 2. 三種授權方法          Shiro 支持三種方式的授權: 編程式:通過寫if/else 授權代碼塊完成: Subject subject = SecurityU

Shiro ini配置

ava rect 成功 logout 不存在 cor pre lte 依賴對象 Shiro.ini配置:   ini配置文件類似Java中的properties(key = value),不過提供了key/value分類的特性,每個部分的key不重復即可   在ecli

Git學習系列2 初配置結構

一 初配置 安裝完成之後,在開始選單裡面找到 "Git --> Git Bash",如下 需要配置使用者名稱和郵箱,如果不清楚是否已配置,可用 git config user.name 和git config user.email進行檢視。 如果沒有進行配置,用gi

shiro學習筆記(7)--cacheManager、sessionManager、rememberMe配置

1、授權:在自定義realm的doGetAuthorizationInfo方法中讀取使用者許可權並授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pri

shiro學習筆記(6)--spring整合可能遇到的問題小結

上篇spring整合shiro後續… spring整合shiro主要是org.apache.shiro.web.filter.authc.FormAuthenticationFilter類。 1、controller @Controller public class HelloSsm {

shiro學習筆記(3)--自定義realm、授權

一:自定義Realm 1、繼承AuthorizingRealm(因為該類中有認證、授權的抽象方法,實現簡單) public class MyRealm1 extends AuthorizingRealm{ @Override public String getName(

Shiro學習筆記(一)--- 認證與授權

一、簡介 Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易於理解的API,您可以快速、輕鬆地獲得任何應用程式,從最小的移動應用程式到最大的網路和企業應用程式。 主要功能 三個核心元件:Subject, Security

Shiro (筆記) InI 配置

https://www.w3cschool.cn/shiro/h5it1if8.html 即使沒接觸過 IoC 容器的知識,如上配置也是很容易理解的: 物件名 = 全限定類名 相對於呼叫 public 無參構造器建立物件 物件名. 屬性名 = 值 相當於呼叫 setter 方法設

SpringMVC的學習(八)——SpringMVC的工作流程相關配置

一、SpringMVC詳細介紹 Spring Web MVC是一種基於Java的實現了Web MVC設計模式的請求驅動型別的輕量級Web框架,即使用了MVC架構模式的思想,將web層進行職責解耦,基於請求驅動指的就是使用請求-響應模型,框架的目的就是幫助我們簡化開發,Spring Web MVC

SpringSecurity學習筆記之二:SpringSecurity結構基本配置

Spring Security3.2分為11個模組,如下表所示: Spring Security3.2引入了新的Java配置方案,完全不在需要通過XML來配置安全性功能。如下,展現了Spring Security最簡單的Java配置: @EnableWebSecurity

SpringBoot+Shiro學習(四):Realm授權

上一節我們講了自定義Realm中的認證(doGetAuthenticationInfo),這節我們繼續講另一個方法doGetAuthorizationInfo授權 授權流程 流程如下: 首先呼叫Subject.isPermitted/hasRole介面,其會委託給Security

go學習之旅——資料庫配置基本用例

golang強大的資料庫驅動 Go與PHP不同的地方是Go沒有官方提供資料庫驅動,而是為開發者開發資料庫驅動定義了一些標準介面,開發者可以 根據定義的介面來開發相應的資料庫驅動,這樣做有一個好處,只要按照標準介面開發的程式碼, 以後需要遷移資料 庫時,不需要任何

Spring系列學習之Spring Cloud Zookeeper服務發現分散式配置

英文原文:https://spring.io/projects/spring-cloud-zookeeper 目錄 概述 特性 快速開始 學習 文件 示例 概述 Spring Cloud Zookeeper通過自動配置和Spring環境以及其他Spring程式

MFC學習筆記——讀寫配置檔案(.ini)和登錄檔

(一)配置檔案(.ini) 配置檔案中經常用到ini檔案,在VC中其函式分別為: //寫入.ini檔案: bool WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR

C++學習:一個通用ini配置檔案操作類

在windows平臺下,簡單的程式可以通過ini檔案實現簡單的配置,簡單適用。在win32 sdk還提供了相應的api來讀取修改ini檔案。ini配置檔案格式為: [section] key=string ... 讀取與修改string的api為ReadPrivatePro

Spring Boot學習一之配置自動配置

一、配置類 1. 匯入其他配置類  你不需要將所有的 @Configuration 放進一個單獨的類, @Import 註解可以用來匯入其他配置類。另外,你也可以使用 @ComponentScan 註解自動收集所有Spring元件,包括 @Configuration 類。 2. 匯入XML配置  如果必

cesium 學習筆記(1)安裝環境配置

 cesium.js 最基本的安裝及環境配置,不同於官方教程,進一步探索官方下載包結構,瞭解node.js、伺服器、Cesium基礎包的部分內容。 相關資源  貌似用國內的網路訪問這些資源速度有點不盡人意,有條件的同學可以科學訪問,或者慢慢等也是可以噠。 安

ElasticSearch學習 - (二)Node.js安裝環境配置之Windows篇

  一、安裝環境 1、本機系統:Windows 10 Pro(64位) 2、Node.js:node-v10.14.2-x64.msi(64位) 二、安裝Node.js步驟 1、下載對應你係統的Node.js版本:https://nodejs.org/en/download