Springboot的使用以及配置.
-
- 1.什麼是Springboot
-
- 1.1 首先我們要了解什麼是Spring
- 1.2 他是如何簡化開發的
- 2 什麼是微服務
- 3. Springboot自動配置原理
- 4.Springboot.run方法分析
- 5.application.yml配置
- 6.深入了解自動配置原理
- 7.靜态資源導入原理
- 8.擴充與裝配Springmvc
- 9.Springboot攔截器具體實作
- 10.spring security的使用
-
- 10.1 簡單的demo
- 11 shiro
-
- 11.1 搭建shiro環境
- 11.2 整合Thymeleaf-shiro
1.什麼是Springboot
1.1 首先我們要了解什麼是Spring
Spring是2003年開發出來的一種輕量級架構,他出現的目的就是簡化企業級應用開發.
1.2 他是如何簡化開發的
-
pojo的輕量性和最小侵入性
pojo就是一個類,spring不會像EJB一樣需要在原本我們的代碼上造成大量改動,需要繼承方法之類的,Spring盡量不會去修改我們的代碼,他隻需要屬性,以及get,set方法就可以了最壞的情況就是在類上添加注解.
-
依賴注入參考
依賴注入的目的就是為了解耦,以前都是我們程式員區new需要的對象,耦合性很大,spring幫我們去配置,通過依賴注入降低耦合性.
springboot就是在之前SSM架構後簡化配置的一個架構,他是通過運作jar包運作的,他内置內建了Tomcat,
-
應用切面
把公共的代碼塊分離出來降低書寫代碼量.
- 使用摸版減少樣闆式代碼書寫量.
了解到這兩個點後,其實Springboot就是一個javaweb架構,他相較于SSM之前的架構,簡化了配置,并且約定大于配置,隻需要在yml檔案中配置屬性.能迅速開發一個web應用.
2 什麼是微服務
所謂的微服務是SOA架構下的最終産物,該架構的設計目标是為了肢解業務,使得服務能夠獨立運作。微服務設計原則:1、各司其職 2、服務高可用和可擴充性.
簡單的講就是将項目中的各項業務進行拆分形成一個單獨的服務并且可以獨立運作提供外部接口.高内聚,低耦合.使用Springboot可以迅速幫我們搭建微服務

什麼是orm
ORM就是ObjectRelationalMapping對象關系映射,簡單的說就是通過執行個體對象的文法去操作關系型資料庫.當使用者流量通路量少是,用于簡化CRUD的資料庫通路架構ORM是影響項目開發的關鍵.
存在的問題:
代碼耦合,開發維護困難
無法針對不同子產品進行針對性優化
無法水準擴充
單點容錯率低,并發能力差
mvc
就是Model View Controller,當使用者量通路加大,ORM架構就顯得力不從心,使用垂直應用架構可以拆分業務,增加并發能力,根據子產品拆分業務.
mvc就是一種設計思想.
RPC Remote Procedure Call Protocol
當應用變多後,應用之間的互動就不可避免.我們可以把核心應用服務抽取出來,形成一個穩定的服務,不同的業務子產品可以調用該服務.
rpc需要解決的問題
通訊問題 : 主要是通過在用戶端和伺服器之間建立TCP連接配接,遠端過程調用的所有交換的資料都在這個連接配接裡傳輸。連接配接可以是按需連接配接,調用結束後就斷掉,也可以是長連接配接,多個遠端過程調用共享同一個連接配接。
尋址問題 : A伺服器上的應用怎麼告訴底層的RPC架構,如何連接配接到B伺服器(如主機或IP位址)以及特定的端口,方法的名稱名稱是什麼,這樣才能完成調用。比如基于Web服務協定棧的RPC,就要提供一個endpoint URI,或者是從UDDI服務上查找。如果是RMI調用的話,還需要一個RMI Registry來注冊服務的位址。
序列化 與 反序列化 : 當A伺服器上的應用發起遠端過程調用時,方法的參數需要通過底層的網絡協定如TCP傳遞到B伺服器,由于網絡協定是基于二進制的,記憶體中的參數的值要序列化成二進制的形式,也就是序列化(Serialize)或編組(marshal),通過尋址和傳輸将序列化的二進制發送給B伺服器。
同理,B伺服器接收參數要将參數反序列化。B伺服器應用調用自己的方法處理後傳回的結果也要序列化給A伺服器,A伺服器接收也要經過反序列化的過程。
SOA
面向服務的架構(SOA)是一個元件模型,它将應用程式的不同功能單元(稱為服務)進行拆分,并通過這些服務之間定義良好的接口和契約聯系起來。接口是采用中立的方式進行定義的,它應該獨立于實作服務的硬體平台、作業系統和程式設計語言。這使得建構在各種各樣的系統中的服務可以以一種統一和通用的方式進行互動。
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個排程中心基于通路壓力實時管理叢集容量,提高叢集使用率。 此時,用于提高機器使用率的 資源排程和治理中心(SOA) 是關鍵。
1 透明化的遠端方法調用
像調用本地方法一樣調用遠端方法;隻需簡單配置,沒有任何API侵入。
2 軟負載均衡及容錯機制
可在内網替代nginx lvs等硬體負載均衡器。
3服務注冊中心自動注冊 & 配置管理
-不需要寫死服務提供者位址,注冊中心基于接口名自動查詢提供者ip。
使用類似zookeeper等分布式協調服務作為服務注冊中心,可以将絕大部分項目配置移入zookeeper叢集。
4服務接口監控與治理
-Dubbo-admin與Dubbo-monitor提供了完善的服務接口管理與監控功能,
針對不同應用的不同接口,可以進行 多版本,多協定,多注冊中心管理。
3. Springboot自動配置原理
1.在pom檔案的spring-boot-starter-parent父工程檔案中
- spring-boot-dependencies幫我們管理了大量依賴版本.
- 所有核心依賴都在父工程中.
2.啟動器
- 簡單說springboot的啟動場景
- 當我們引入一個web啟動器,他會自動幫我們引入所有關于web的依賴.
- springboot将所有的功能場景程式設計一個啟動器我們需要哪個就引入哪個.
3.主程式
-
@SpringbootApplication (标注這是個Springboot應用)
在該注解下還有三個注解
-
@SpringBootConfiguration
它就是springboot的配置
-
@Configuration
這說明這本質是一個元件是一個spring的一個元件
-
-
@EnableAutoConfiguration
開啟自動配置功能,自動導入配置,他會根據你的maven導入的包自動配置.
-
@AutoConfigurationPackage
将主動配置類的包作為自動配置包,這個注解是自動配置包,主要是使用的@Import來給Spring容器中導入一個元件 ,這裡導入的是Registrar.class。
-
@Import({Registrar.class})
導入選擇器
@Import({AutoConfigurationImportSelector.class})
導入一個類到ioc容器中,meta-inf根據spring。factory配置
@componentscan
它是将我們啟動器所在包下的元件總動裝配到spring容器中
springboot根據配置檔案自動裝配所屬依賴的類,在通過動态代理注入到spring容器中
-
-
-
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));//是通過這個方法擷取掃描的包路徑
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
}
}
那麼那個中繼資料metadata是什麼呢?
說白了就是将主配置類(即@SpringBootApplication标注的類)的所在包及子包裡面所有元件掃描加載到Spring容器。是以包名一定要注意。
-
@Import({AutoConfigurationImportSelector.class})
導入選擇器,裡面有環境,資源加載器,bean加載器等待.
裡面有個selectImport方法可以選擇元件,就是在pom中配置的的一些元件
getAutoConfigurationEntry方法中擷取一些配置 ,将所有需要導入的元件以全類名的方式傳回;這些元件就會被添加到容器中。
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
有了自動配置類,免去了我們手動編寫配置注入功能元件等的工作。
那他是如何擷取到這些配置類的呢,看看下面面這個方法:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
進入getAutoConfigurationEntry(annotationMetadata);方法
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
進入getCandidateConfigurations(annotationMetadata, attributes);這個方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
我們發現它會從META-INF/spring.factories這個檔案中擷取資源通過properties加載
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryImplementationName = var9[var11];
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
Springboot在啟動的時候會從META-INF/spring.factories中擷取EnableAutoConfiguration指定的值,将這些值作為自動配置類導入到容器中,自動配置類就生效,幫我們進行自動配置工作。以前我們需要自己配置的東西,自動配置類都幫我們完成了。
總體的整合方案以及配置都在spring.factories中
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
//中繼資料
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
}
}
總結.springboot配置原理
springboot自動配置原理簡單的講就是在@SpringbootApplication中有兩個核心注解第一個是springbootConfiguration,它表明這是一個spring元件,還有一個注解@EnableAutoConfiguration該注解裡面的内容有@AutoConfigurationPackage 他的作用是自動配置包,打開該注解發現裡面還有個@import(Registrar)導入包的注冊器.關系是@componentScan掃描到的包到Registrar.
該注解的作用是導入需要的元件在SpringbootApp包下的所有元件,中繼資料.注冊進去
@EnableAutoConfiguration中另一個注解
自動配置導入選擇器@Import({AutoConfigurationImportSelector.class}),
該類中有一個selectImports方法,擷取所有配置類,将所有需要導入的元件以全類名的方式傳回;通過spring.factories.
Spring Boot在啟動的時候從類路徑下的META-INF/spring.factories中擷取EnableAutoConfiguration指定的值,将這些值作為自動配置類導入到容器中,自動配置類就生效,幫我們進行自動配置工作。以前我們需要自己配置的東西,自動配置類都幫我們完成了。
為什麼那麼多配置有的會不生效
需要導入start啟動類才可以生效,有個核心注解@ConditionalONXXXX,如果滿足這個條件才會生效.
結論
Springboot配置中通過@SpringbootApplication注解來去掃描與加載配置與元件,但是不一定都會生效,需要導入對應的start啟動類jar包.
1.springboot 啟動的時候會從 /META-INF/spring.factories 通過url.nextElement得到配置資訊.
2.将這些自動配置類導入進去,配置類就會生效,當然也不是全部生效會有@Conditionalon判斷
3.autoConfigure包下的配置檔案會以全類名的方式傳回并添加到容器中.
4.容器中有很多XXXAutoConfigure配置檔案,導入後就會導入所有元件.比如@Bean.
有了自動配置類,就會免去我們手動編寫.
4.Springboot.run方法分析
該方法主要分為兩部分,一部分是springApplication執行個體化,二是run方法執行.
SpringbootApplication
這個類做了以下四件事:
- 根據導入的依賴包推斷是web應用還是java應用
- 查找并加載所有初始化器,設定到initializers屬性中
- 找出所有應用程式監聽器設定到listeners屬性中
- 推斷并設定main方法定義表找到運作主類.
5.application.yml配置
在該檔案中我們可以對已有預設配置的變量進行修改,也可以寫自定義類并将值指派進去.
編寫person類添加注解@ConfigurationProperties(prefix = “person”)
運作輸出
運作成功
除了使用yml方法外還可以使用
PropertyResource注解
cp隻要寫一次就可以,使用@value需要全部添加.
cp支援松散綁定 就是類似配置駝峰的東西.
cp支援資料校驗
yml可以封裝複雜對象,pro不能
總結:
- yml和properties都可以擷取到值,但是推薦使用yml.
- 隻需要配置檔案的某個值可以使用@value
JSR303資料校驗
首先我們需要引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
在@Configuration注解下添加@Validated注解
在你需要校驗的成員變量添加校驗注解
當我們測試運作後報錯:這不是一個合法的電子郵箱
配置檔案的位置
可以放在
- file/ 項目根目錄下
- file/config 項目config目錄下
- classpath: resource目錄下
- classpath/config resource/config目錄下
優先級從大到小:
2>1>4>3
springboot 多環境配置
在開發過程中會有測試環境,線上環境,開發環境,那麼該如何切換呢?
這時需要配置spring.profile.active
使用dev環境直接修改
spring:
profiles:
active: dev
當然我們也可以把所有的環境都寫在一個配置檔案當中
但需要—分隔符.
6.深入了解自動配置原理
配置檔案與spring.factories的聯系
首先我們随便打開一個自動配置類檔案
該類中的@ConditionalOnProperty
prefix=“spring.application.admin”
對應的是application.yml中的配置字首
成員變量可以通過配置application.yml來指派
7.靜态資源導入原理
要知道原理一定要看源碼。
- 輕按兩下 shift進入WebMvcAutoConfig配置類裡面有我們想要的答案。
- 找到WebMvcAutoConfigurationAdapter靜态類,找到addResourceHandlers這個方法
分析下列代碼
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
}
首先看第一個判斷if(!this.resourceProperties.isAddMappings())
如果自定義了靜态資源則直接生效,我們自定義的路徑為靜态路徑。
那麼怎麼自定義靜态路徑呢?
找到源碼中webMvcproperties
3. 繼續往下走看到關于webjars相關的,他表示通過maven引入的js檔案,這裡不做介紹。重點要看接下來方法中的this
點進去裡面有屬性是配置自定義靜态資源路徑的。
staticPathPattern
我麼直接可以再yml檔案中設定`
spring:
mvc:
static-path-pattern: /kui
同時在該類中 還有個this.resourceProperties,點進去一直
會發現最後有個配置靜态資源的數組
就在這裡定義了我們靜态資源的路徑。如果我們不配置自定義路徑那麼一共有五個靜态資源路徑classpath:/META-INF/resources/", “classpath:/resources/”, “classpath:/static/”, "classpath:/public/和/**
優先級:resource》static》public
這裡要注意的是配置自定義路徑後,預設的靜态資源路徑就不好使了
8.擴充與裝配Springmvc
Spring Boot為Spring MVC提供了自動配置,可與大多數應用程式完美配合。
自動配置會在Spring的預設設定之上添加以下功能:
包含ContentNegotiatingViewResolver和BeanNameViewResolver Bean。
支援服務靜态資源,包括對WebJars的支援.
自動注冊Converter,GenericConverter 比如傳入user中的字段,springmvc會幫助我們自動封裝,Formatter Bean 封裝日期形式。
對HttpMessageConverters的支援。比如轉化json
自動注冊MessageCodesResolver。
靜态index.html支援。
自定義Favicon支援(在本文檔後面介紹)。
自動使用ConfigurableWebBindingInitializer Bean(在本文檔後面介紹)。
如果您想保留Spring Boot MVC功能并想添加其他MVC配置(攔截器,格式化程式,視圖控制器和其他功能),則可以添加自己的類型為WebMvcConfigurer的@Configuration類,但不添加@EnableWebMvc。如果希望提供RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定義執行個體,則可以聲明一個WebMvcRegistrationsAdapter執行個體以提供此類元件。
那麼為什麼不能加@EnableWebMvc呢.點開源碼
發現該注解導入了一個類
@Import({DelegatingWebMvcConfiguration.class})
打開該類發現他繼承了WebMvcConfigurationSupport 這個類.
我們再次打開webmvc自動配置類
發現@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})這個注解
那麼這也就意味着當我們使用這個@EnableWebMvc注解會使整個自動配置類失效崩掉.
9.Springboot攔截器具體實作
登入連接配接器 使用intercepter 攔截
10.spring security的使用
導入包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Spring Security 是針對Spring項目的安全架構,也是Spring Boot底層安全子產品預設的技術選型,他可以實作強大的Web安全控制,對于安全控制,我們僅需要引入 spring-boot-starter-security 子產品,進行少量的配置,即可實作強大的安全管理!
記住幾個類:
WebSecurityConfigurerAdapter:自定義Security政策
AuthenticationManagerBuilder:自定義認證政策
@EnableWebSecurity:開啟WebSecurity模式
Spring Security的兩個主要目标是 “認證” 和 “授權”(通路控制)。
“認證”(Authentication)
身份驗證是關于驗證您的憑據,如使用者名/使用者ID和密碼,以驗證您的身份。
身份驗證通常通過使用者名和密碼完成,有時與身份驗證因素結合使用。
“授權” (Authorization)
授權發生在系統成功驗證您的身份後,最終會授予您通路資源(如資訊,檔案,資料庫,資金,位置,幾乎任何内容)的完全權限。
這個概念是通用的,而不是隻在Spring Security 中存在。
10.1 簡單的demo
實作使用者登入攔截請求:
首先寫一個配置類
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/","index").permitAll().antMatchers("/main").hasRole("VIP");
//設定登入跳轉頁面以及失敗跳轉頁面成功跳轉頁面
http.formLogin().loginPage("/").loginProcessingUrl("/user/login")
.failureUrl("/").defaultSuccessUrl("/main").permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//授權,這裡要注意密碼需要寫死處理否則會報錯在 2.1版本中
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).
withUser("kui").password(new BCryptPasswordEncoder().encode("123")).roles("VIP");
}
}
但是 使用者登入後,有些東西是不想讓沒有權限的人看到的,那麼如何在前端頁面控制呢?
導入Thymeleaf和security整合包
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
zaihtml引入該标簽
11 shiro
11.1 搭建shiro環境
Apache Shiro 是 Java 的一個安全架構。目前,使用 Apache Shiro 的人越來越多,因為它相當簡單,對比 Spring Security,可能沒有 Spring Security 做的功能強大,但是在實際工作時可能并不需要那麼複雜的東西,是以使用小而簡單的 Shiro 就足夠了。對于它倆到底哪個好,這個不必糾結,能更簡單的解決項目問題就好了。
首先引入maven依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>
編寫shiroconfig
@Configuration
public class ShiroConfig {
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(UserRealm userRealm){
DefaultWebSecurityManager d=new DefaultWebSecurityManager();
d.setRealm(userRealm);
return d;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean (DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean s=new ShiroFilterFactoryBean();
s.setSecurityManager(defaultWebSecurityManager);
Map filterMap=new LinkedHashMap();
filterMap.put("/main","authc");
s.setFilterChainDefinitionMap(filterMap);
s.setLoginUrl("/");
s.setSuccessUrl("/main");
//未授權跳轉url
s.setUnauthorizedUrl("/");
return s;
}
}
編寫userrealm
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("執行了授權");
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
String s = (String) SecurityUtils.getSubject().getPrincipal();
info.addStringPermission(s);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usertoken=(UsernamePasswordToken)authenticationToken;
if (!usertoken.getUsername().equals("kui"))
throw new UnknownAccountException();
//這裡第一個參數可以傳任意對象,最終擷取到的隻不過是授權位址。我這裡直接傳入授權位址
return new SimpleAuthenticationInfo("main","123","");
}
}
11.2 整合Thymeleaf-shiro
導入依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
配置shiroconfig
@Configuration
public class ShiroConfig {
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(UserRealm userRealm){
DefaultWebSecurityManager d=new DefaultWebSecurityManager();
d.setRealm(userRealm);
return d;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean (DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean s=new ShiroFilterFactoryBean();
s.setSecurityManager(defaultWebSecurityManager);
Map filterMap=new LinkedHashMap();
filterMap.put("/main","authc");
filterMap.put("/main","perms[main]");
s.setFilterChainDefinitionMap(filterMap);
s.setUnauthorizedUrl("/noauth");
s.setLoginUrl("/");
s.setSuccessUrl("/main");
return s;
}
//需要使用Thymeleaf必需配置bean
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
}