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

SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例

 更新時(shí)間:2018年03月07日 14:45:07   作者:BlueKitty1210  
這篇文章主要介紹了SpringBoot集成Shiro進(jìn)行權(quán)限控制和管理的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

shiro

apache shiro 是一個(gè)輕量級的身份驗(yàn)證與授權(quán)框架,與spring security 相比較,簡單易用,靈活性高,springboot本身是提供了對security的支持,畢竟是自家的東西。springboot暫時(shí)沒有集成shiro,這得自己配。

1 . 添加依賴

<dependency> 
  <groupId>org.apache.shiro</groupId> 
  <artifactId>shiro-spring</artifactId> 
  <version>1.2.5</version> 
</dependency> 
<dependency> 
  <groupId>org.apache.shiro</groupId> 
  <artifactId>shiro-ehcache</artifactId> 
  <version>1.2.5</version> 
</dependency> 

2 . 編寫Shiro配置類

package com.xbz.web.system.config;  
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; 
import org.apache.shiro.authc.credential.CredentialsMatcher; 
import org.apache.shiro.authc.credential.HashedCredentialsMatcher; 
import org.apache.shiro.cache.ehcache.EhCacheManager; 
import org.apache.shiro.codec.Base64; 
import org.apache.shiro.session.SessionListener; 
import org.apache.shiro.session.mgt.SessionManager; 
import org.apache.shiro.session.mgt.eis.MemorySessionDAO; 
import org.apache.shiro.session.mgt.eis.SessionDAO; 
import org.apache.shiro.spring.LifecycleBeanPostProcessor; 
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 
import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 
import org.apache.shiro.web.mgt.CookieRememberMeManager; 
import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 
import org.apache.shiro.web.servlet.SimpleCookie; 
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; 
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.DependsOn;  
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.LinkedHashMap; 
import java.util.Map; 
/** 
 * shiro配置類 
 * ApacheShiro核心通過Filter來實(shí)現(xiàn)權(quán)限控制和攔截 , 就好像SpringMVC通過DispachServlet來主控制請求分發(fā)一樣 . 
 * 既然是使用Filter , 即是通過URL規(guī)則來進(jìn)行過濾和權(quán)限校驗(yàn) , 所以我們需要定義一系列關(guān)于URL的規(guī)則和訪問權(quán)限 
 */ 
@Configuration 
public class ShiroConfiguration { 
  /** 
   * DefaultAdvisorAutoProxyCreator , Spring的一個(gè)bean , 由Advisor決定對哪些類的方法進(jìn)行AOP代理 . 
   */ 
  @Bean 
  @ConditionalOnMissingBean 
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { 
    DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator(); 
    defaultAAP.setProxyTargetClass(true); 
    return defaultAAP; 
  } 
 
  /** 
   * ShiroFilterFactoryBean : 為了生成ShiroFilter , 處理攔截資源文件問題 . 
   * 它主要保持了三項(xiàng)數(shù)據(jù) , securityManager , filters , filterChainDefinitionManager . 
   * 注意 : 單獨(dú)一個(gè)ShiroFilterFactoryBean配置是或報(bào)錯(cuò)的 , 因?yàn)樵诔跏蓟疭hiroFilterFactoryBean的時(shí)候需要注入:SecurityManager 
   * 
   * FilterChain定義說明 
   * 1 . 一個(gè)URL可以配置多個(gè)Filter , 使用逗號分隔 
   * 2 . 當(dāng)設(shè)置多個(gè)過濾器時(shí) , 全部驗(yàn)證通過 , 才視為通過 
   * 3 . 部分過濾器可指定參數(shù) , 如perms , roles 
   * 
   */ 
  @Bean 
  public ShiroFilterFactoryBean shiroFilterFactoryBean() { 
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 
    shiroFilterFactoryBean.setSecurityManager(securityManager()); 
    shiroFilterFactoryBean.setLoginUrl("/login");//不設(shè)置默認(rèn)找web工程根目錄下的login.jsp頁面 
    shiroFilterFactoryBean.setSuccessUrl("/index");//登錄成功之后要跳轉(zhuǎn)的連接 
    shiroFilterFactoryBean.setUnauthorizedUrl("/403");//未授權(quán)跳轉(zhuǎn)頁面 
    /* //自定義攔截器 , 多個(gè)filter的設(shè)置 */ 
//    Map<String, Filter> filters = new LinkedHashMap<>(); 
//    LogoutFilter logoutFilter = new LogoutFilter();//限制同一帳號同時(shí)在線的個(gè)數(shù)?;騿吸c(diǎn)登錄等 
//    logoutFilter.setRedirectUrl("/login"); 
//    filters.put("logout",null); 
//    shiroFilterFactoryBean.setFilters(filters);  
    Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); 
    //filterChainDefinitionManager必須是LinkedHashMap因?yàn)樗仨毐WC有序 
    filterChainDefinitionMap.put("/css/**", "anon");//靜態(tài)資源不要求權(quán)限 , 若有其他目錄下文件(如js,img等)也依此設(shè)置 
    filterChainDefinitionMap.put("/", "anon"); 
    filterChainDefinitionMap.put("/login", "anon");//配置不需要權(quán)限訪問的部分url 
    filterChainDefinitionMap.put("/logout", "logout"); 
    filterChainDefinitionMap.put("/user/**", "authc,roles[ROLE_USER]");//用戶為ROLE_USER 角色可以訪問 . 由用戶角色控制用戶行為 .  
    filterChainDefinitionMap.put("/events/**", "authc,roles[ROLE_ADMIN]"); 
    //    filterChainDefinitionMap.put("/user/edit/**", "authc,perms[user:edit]");// 這里為了測試 , 固定寫死的值 , 也可以從數(shù)據(jù)庫或其他配置中讀取 , 此處是用權(quán)限控制 
 
    filterChainDefinitionMap.put("/**", "authc");//需要登錄訪問的資源 , 一般將/**放在最下邊 
 
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); 
    return shiroFilterFactoryBean; 
  } 
 
  //region Cookie及Session 
  // ==================== Cookie及Session管理 begin ==================== 
  private static final String COOKIE_NAME = "rememberMe"; 
  /** cookie對象管理 */ 
  public SimpleCookie rememberMeCookie(){ 
    //這個(gè)參數(shù)是cookie的名稱,對應(yīng)前端的checkbox的name = rememberMe 
    SimpleCookie simpleCookie = new SimpleCookie(COOKIE_NAME); 
    simpleCookie.setMaxAge(604800);//記住我cookie生效時(shí)間7天 ,單位秒 
    return simpleCookie; 
  } 
 
  /** cookie管理對象 : 記住我功能 */ 
  public CookieRememberMeManager rememberMeManager(){ 
    CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); 
    cookieRememberMeManager.setCookie(rememberMeCookie()); 
    cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));//rememberMe cookie加密的密鑰 建議每個(gè)項(xiàng)目都不一樣 默認(rèn)AES算法 密鑰長度(128 256 512 位) 
    return cookieRememberMeManager; 
  } 
 
  @Bean 
  SessionDAO sessionDAO() { 
    return new MemorySessionDAO(); 
  } 
 
  @Bean 
  public SessionManager sessionManager() { 
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); 
    Collection<SessionListener> listeners = new ArrayList<>(); 
    listeners.add(new BDSessionListener()); 
    sessionManager.setSessionListeners(listeners); 
    sessionManager.setSessionDAO(sessionDAO()); 
    return sessionManager; 
  } 
  // ==================== Cookie及Session管理 end ==================== 
  //endregion 
 
  /** 
   * SecurityManager : 核心安全事務(wù)管理器 , 權(quán)限管理 
   * 這個(gè)類組合了登陸 , 登出 , 權(quán)限 , session的處理 . 是個(gè)比較重要的類 . 
   */ 
  @Bean(name = "securityManager") 
  public DefaultWebSecurityManager securityManager() { 
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 
    securityManager.setRealm(shiroRealm()); 
    securityManager.setCacheManager(ehCacheManager());////用戶授權(quán)/認(rèn)證信息Cache, 采用EhCache 緩存 
 
    // 自定義session管理 使用redis 
    securityManager.setSessionManager(sessionManager()); 
 
    //注入記住我管理器; 
    securityManager.setRememberMeManager(rememberMeManager()); 
    return securityManager; 
  } 
 
  /** 
   * ShiroRealm , 這是個(gè)自定義的認(rèn)證類 , 繼承自AuthorizingRealm , 
   * 負(fù)責(zé)用戶的認(rèn)證和權(quán)限的處理 , 可以參考JdbcRealm的實(shí)現(xiàn) . 
   */ 
  @Bean 
  @DependsOn("lifecycleBeanPostProcessor") 
  public ShiroRealm shiroRealm(CredentialsMatcher matcher) { 
    ShiroRealm realm = new ShiroRealm(); 
    realm.setCredentialsMatcher(matcher);//密碼校驗(yàn)實(shí)現(xiàn) 
    return realm; 
  } 
 
  /** 
   * EhCacheManager , 緩存管理 
   * 用戶登陸成功后 , 把用戶信息和權(quán)限信息緩存起來 , 然后每次用戶請求時(shí) , 放入用戶的session中 , 如果不設(shè)置這個(gè)bean , 每個(gè)請求都會(huì)查詢一次數(shù)據(jù)庫 . 
   */ 
  @Bean 
  @DependsOn("lifecycleBeanPostProcessor") 
  public EhCacheManager ehCacheManager() { 
    EhCacheManager em = new EhCacheManager(); 
    em.setCacheManagerConfigFile("classpath:config/ehcache.xml");//配置文件路徑 
    return em; 
  } 
 
  /** 
   * LifecycleBeanPostProcessor , 這是個(gè)DestructionAwareBeanPostProcessor的子類 , 
   * 負(fù)責(zé)org.apache.shiro.util.Initializable類型bean的生命周期的 , 初始化和銷毀 . 
   * 主要是AuthorizingRealm類的子類 , 以及EhCacheManager類 . 
   */ 
  @Bean(name = "lifecycleBeanPostProcessor") 
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { 
    return new LifecycleBeanPostProcessor(); 
  } 
 
  /** 
   * HashedCredentialsMatcher , 這個(gè)類是為了對密碼進(jìn)行編碼的 , 
   * 防止密碼在數(shù)據(jù)庫里明碼保存 , 當(dāng)然在登陸認(rèn)證的時(shí)候 , 
   * 這個(gè)類也負(fù)責(zé)對form里輸入的密碼進(jìn)行編碼 
   * 處理認(rèn)證匹配處理器:如果自定義需要實(shí)現(xiàn)繼承HashedCredentialsMatcher 
   */ 
  @Bean(name = "hashedCredentialsMatcher") 
  public HashedCredentialsMatcher hashedCredentialsMatcher() { 
    HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); 
    credentialsMatcher.setHashAlgorithmName("MD5");//指定加密方式方式,也可以在這里加入緩存,當(dāng)用戶超過五次登陸錯(cuò)誤就鎖定該用戶禁止不斷嘗試登陸 
    credentialsMatcher.setHashIterations(2); 
    credentialsMatcher.setStoredCredentialsHexEncoded(true); 
    return credentialsMatcher; 
  } 
 
  /** 
   * AuthorizationAttributeSourceAdvisor , shiro里實(shí)現(xiàn)的Advisor類 , 
   * 內(nèi)部使用AopAllianceAnnotationsAuthorizingMethodInterceptor來攔截用以下注解的方法 . 
   */ 
  @Bean 
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { 
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); 
    advisor.setSecurityManager(securityManager()); 
    return advisor; 
  } 
 
  //thymeleaf模板引擎和shiro整合時(shí)使用 
  @Bean 
  public ShiroDialect shiroDialect() { 
    return new ShiroDialect(); 
  } 
} 

3 . 自定義Realm驗(yàn)證類

package com.yiyun.web.system.config;  
import com.yiyun.dao.master.UserDao; 
import com.yiyun.domain.UserDO; 
import com.yiyun.web.common.utils.ShiroUtils; 
import com.yiyun.web.system.service.MenuService; 
import org.apache.shiro.SecurityUtils; 
import org.apache.shiro.authc.*; 
import org.apache.shiro.authz.AuthorizationInfo; 
import org.apache.shiro.authz.SimpleAuthorizationInfo; 
import org.apache.shiro.realm.AuthorizingRealm; 
import org.apache.shiro.session.Session; 
import org.apache.shiro.subject.PrincipalCollection; 
import org.springframework.beans.factory.annotation.Autowired;  
import java.util.*; 
 
/** 
 * 獲取用戶的角色和權(quán)限信息 
 */ 
public class ShiroRealm extends AuthorizingRealm { 
 
  // 一般這里都寫的是servic 
  @Autowired 
  private UserDao userMapper; 
  @Autowired 
  private MenuService menuService; 
 
  /** 
   * 登錄認(rèn)證 一般情況下 , 登錄成功之后就給當(dāng)前用戶進(jìn)行權(quán)限賦予了 
   * 根據(jù)用戶的權(quán)限信息做授權(quán)判斷,這一步是以doGetAuthenticationInfo為基礎(chǔ)的,只有在有用戶信息后才能根據(jù)用戶的角色和授權(quán)信息做判斷是否給用戶授權(quán),因此這里的Roles和Permissions是用戶的兩個(gè)重點(diǎn)判斷依據(jù) 
   * @param authenticationToken 
   * @return 
   * @throws AuthenticationException 
   */ 
  @Override 
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { 
    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; 
    UserDo user = userMapper.findByName(token.getUsername());//查出是否有此用戶 
 
    if(user != null){ 
      // 若存在,將此用戶存放到登錄認(rèn)證info中,無需自己做密碼對比,Shiro會(huì)為我們進(jìn)行密碼對比校驗(yàn) 
      List<URole> rlist = uRoleDao.findRoleByUid(user.getId());//獲取用戶角色 
      List<UPermission> plist = uPermissionDao.findPermissionByUid(user.getId());//獲取用戶權(quán)限 
      List<String> roleStrlist=new ArrayList<String>();////用戶的角色集合 
      List<String> perminsStrlist=new ArrayList<String>();//用戶的權(quán)限集合 
      for (URole role : rlist) { 
        roleStrlist.add(role.getName()); 
      } 
      for (UPermission uPermission : plist) { 
        perminsStrlist.add(uPermission.getName()); 
      } 
      user.setRoleStrlist(roleStrlist); 
      user.setPerminsStrlist(perminsStrlist); 
      Session session = SecurityUtils.getSubject().getSession(); 
      session.setAttribute("user", user);//成功則放入session 
      // 若存在,將此用戶存放到登錄認(rèn)證info中,無需自己做密碼對比,Shiro會(huì)為我們進(jìn)行密碼對比校驗(yàn) 
      return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); 
    } 
    return null; 
  } 
 
  /** 
   * 權(quán)限認(rèn)證 
   * 獲取用戶的權(quán)限信息,這是為下一步的授權(quán)做判斷,獲取當(dāng)前用戶的角色和這些角色所擁有的權(quán)限信息 
   * @param principalCollection 
   * @return 
   */ 
  @Override 
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 
    //獲取當(dāng)前登錄輸入的用戶名,等價(jià)于(String) principalCollection.fromRealm(getName()).iterator().next(); 
//    String loginName = (String) super.getAvailablePrincipal(principalCollection); 
    UserDo user = (UserDo) principalCollection.getPrimaryPrincipal(); 
//    //到數(shù)據(jù)庫查是否有此對象 
//    User user = null;// 實(shí)際項(xiàng)目中,這里可以根據(jù)實(shí)際情況做緩存,如果不做,Shiro自己也是有時(shí)間間隔機(jī)制,2分鐘內(nèi)不會(huì)重復(fù)執(zhí)行該方法 
//    user = userMapper.findByName(loginName); 
    if (user != null) { 
      //權(quán)限信息對象info,用來存放查出的用戶的所有的角色(role)及權(quán)限(permission) 
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 
      //用戶的角色集合 
      info.addRoles(user.getRoleStrlist()); 
      //用戶的權(quán)限集合 
      info.addStringPermissions(user.getPerminsStrlist()); 
 
      return info; 
    } 
    // 返回null的話,就會(huì)導(dǎo)致任何用戶訪問被攔截的請求時(shí),都會(huì)自動(dòng)跳轉(zhuǎn)到unauthorizedUrl指定的地址 
    return null; 
  } 
} 

4 . 最后看一下ehcache的配置文件

<?xml version="1.0" encoding="UTF-8"?> 
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" 
  updateCheck="false"> 
  <diskStore path="java.io.tmpdir/Tmp_EhCache" />  
  <!-- 
    name:緩存名稱。 
    maxElementsInMemory:緩存最大數(shù)目 
    maxElementsOnDisk:硬盤最大緩存?zhèn)€數(shù)。 
    eternal:對象是否永久有效,一但設(shè)置了,timeout將不起作用。 
    overflowToDisk:是否保存到磁盤,當(dāng)系統(tǒng)當(dāng)機(jī)時(shí) 
    timeToIdleSeconds:設(shè)置對象在失效前的允許閑置時(shí)間(單位:秒)。僅當(dāng)eternal=false對象不是永久有效時(shí)使用,可選屬性,默認(rèn)值是0,也就是可閑置時(shí)間無窮大。 
    timeToLiveSeconds:設(shè)置對象在失效前允許存活時(shí)間(單位:秒)。最大時(shí)間介于創(chuàng)建時(shí)間和失效時(shí)間之間。僅當(dāng)eternal=false對象不是永久有效時(shí)使用,默認(rèn)是0.,也就是對象存活時(shí)間無窮大。 
    diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù) Whether the disk store persists between restarts of the Virtual Machine. The default value is false. 
    diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤緩存)的緩存區(qū)大小。默認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)。 
    diskExpiryThreadIntervalSeconds:磁盤失效線程運(yùn)行時(shí)間間隔,默認(rèn)是120秒。 
    memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí),Ehcache將會(huì)根據(jù)指定的策略去清理內(nèi)存。默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先出)或是LFU(較少使用)。 
    clearOnFlush:內(nèi)存數(shù)量最大時(shí)是否清除。 
     memoryStoreEvictionPolicy: 
      Ehcache的三種清空策略; 
      FIFO,first in first out,這個(gè)是大家最熟的,先進(jìn)先出。 
      LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點(diǎn)就是講一直以來最少被使用的。如上面所講,緩存的元素有一個(gè)hit屬性,hit值最小的將會(huì)被清出緩存。 
      LRU,Least Recently Used,最近最少使用的,緩存的元素有一個(gè)時(shí)間戳,當(dāng)緩存容量滿了,而又需要騰出地方來緩存新的元素的時(shí)候,那么現(xiàn)有緩存元素中時(shí)間戳離當(dāng)前時(shí)間最遠(yuǎn)的元素將被清出緩存。 
  --> 
 
  <defaultCache eternal="false" maxElementsInMemory="1000" 
    overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0" 
    timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" /> 
  <!-- 登錄記錄緩存鎖定10分鐘 --> 
  <cache name="passwordRetryCache" 
      maxEntriesLocalHeap="2000" 
      eternal="false" 
      timeToIdleSeconds="3600" 
      timeToLiveSeconds="0" 
      overflowToDisk="false" 
      statistics="true"> 
  </cache> 
</ehcache> 

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入了解Spring中Bean的作用域和生命周期

    深入了解Spring中Bean的作用域和生命周期

    這篇文章主要介紹了深入了解Spring中Bean的作用域和生命周期,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 在SpringBoot框架中實(shí)現(xiàn)打印響應(yīng)的日志

    在SpringBoot框架中實(shí)現(xiàn)打印響應(yīng)的日志

    這篇文章主要介紹了在SpringBoot框架中實(shí)現(xiàn)打印響應(yīng)的日志,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Java如何用時(shí)間戳重命名上傳的文件

    Java如何用時(shí)間戳重命名上傳的文件

    這篇文章主要介紹了Java如何用時(shí)間戳重命名上傳的文件問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • java 文件大數(shù)據(jù)Excel下載實(shí)例代碼

    java 文件大數(shù)據(jù)Excel下載實(shí)例代碼

    這篇文章主要介紹了java 文件大數(shù)據(jù)Excel下載實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Java Shutdown Hook場景使用及源碼分析

    Java Shutdown Hook場景使用及源碼分析

    shutdown hook 就是一個(gè)簡單的已初始化但是未啟動(dòng)的線程,本文詳細(xì)的介紹了Java Shutdown Hook場景使用及源碼分析,感興趣的朋友可以參考一下
    2021-06-06
  • java枚舉類型-Enum

    java枚舉類型-Enum

    本文詳細(xì)介紹了 Java1.5 引入的新特性枚舉中的關(guān)鍵字enum,運(yùn)用大量的代碼加以解釋,相信可以幫助到正在學(xué)習(xí)該知識的小伙伴,大家可以參考一下
    2021-08-08
  • Java之Class.forName()用法案例詳解

    Java之Class.forName()用法案例詳解

    這篇文章主要介紹了Java之Class.forName()用法案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Spring Data Jpa的四種查詢方式詳解

    Spring Data Jpa的四種查詢方式詳解

    這篇文章主要介紹了Spring Data Jpa的四種查詢方式詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot中的掃描注解使用詳解

    SpringBoot中的掃描注解使用詳解

    為了使Spring Boot應(yīng)用程序能夠掃描并識別特定或自定義注解,通常的做法是在創(chuàng)建這些注解之后,在配置類中通過@ComponentScan指定基礎(chǔ)包路徑,并設(shè)置過濾條件來包含所需的注解,本文給大家介紹了Spring Boot中的掃描注解如何使用,需要的朋友可以參考下
    2025-01-01
  • mybatisplus?復(fù)合主鍵(多主鍵)?CRUD示例詳解

    mybatisplus?復(fù)合主鍵(多主鍵)?CRUD示例詳解

    這篇文章主要介紹了mybatisplus?復(fù)合主鍵(多主鍵)?CRUD實(shí)例詳解,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03

最新評論

井冈山市| 瑞金市| 巴青县| 黔南| 古蔺县| 平远县| 金门县| 平谷区| 绥棱县| 庐江县| 吴堡县| 顺平县| 金寨县| 新余市| 临泉县| 沭阳县| 永和县| 高雄市| 西贡区| 高青县| 万源市| 陇西县| 南康市| 乐至县| 南部县| 静乐县| 灵寿县| 雷波县| 综艺| 陇南市| 西宁市| 宜都市| 巧家县| 博爱县| 营山县| 大厂| 于田县| 中阳县| 泰顺县| 交城县| 辽中县|