spring mvc+Mybatis整合shiro 第一章 整體配置

前段時間研究了一下shiro,因爲看不懂英文所以學習過程頗爲曲折,後來整合shiro想寫一個sso結果這段時間又寫不下去了只好來寫寫博客了。

最初學shiro是在百度搜教程,說實話那些教程除了開濤寫的其它人寫的確實不怎麼樣,而且開濤的教程也不是特別詳細的那種,所以我在這給大家寫一個整合後的完整教程。

shiro的設計思想我在這就不多說了,實話我說只明白一小半甚至一小半都沒有,要說思想開濤的博客的前幾章講的很好,所以我在這不重複了這裏我只講些實用的東西能讓你快速上手的。

先上個Spring mvc的配置文件,具體都是什麼配置請自行百度這個教程太多了我在這就不講了。

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xmlns:context="http://www.springframework.org/schema/context"
		xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
		http://www.springframework.org/schema/context"
	default-lazy-init="false">

	<description>Spring公共配置 </description>

	<!-- 定義受環境影響易變的變量 -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
		<property name="ignoreResourceNotFound" value="true" />
		<property name="locations">
			<list>
				<!-- 標準配置 -->
				<value>classpath*:/application.properties</value>
				<value>classpath*:/config/shiro.properties</value>
			</list>
		</property>
	</bean>
	
	<!--  激活 @Required @Autowired,JSR 250's @PostConstruct, @PreDestroy and @Resource 等標註 -->
	<context:annotation-config />

	<!-- 使用annotation 自動註冊bean,並保證@Required,@Autowired的屬性被注入 -->
	<context:component-scan base-package="com.sso" >
	 	 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>

	<!-- 數據源配置,使用應用內的DBCP數據庫連接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<!-- Connection Info -->
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />

		<!-- Connection Pooling Info -->
		<property name="initialSize" value="${dbcp.initialSize}" />
		<property name="maxActive" value="${dbcp.maxActive}" />
		<property name="maxIdle" value="${dbcp.maxIdle}" />
		<property name="defaultAutoCommit" value="false" />
	</bean>

	<!-- 數據源配置,使用應用服務器的數據庫連接池 -->
	<!--<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ExampleDB" />-->

	<!-- Mybatis配置 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="typeAliasesPackage" value= "com.sso.entity,;" />
	</bean>
	
	<!-- scan for mappers and let them be autowired -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value= "com.sso.dao,;" />
    </bean>
    

	<!-- Transaction manager for a single JDBC DataSource -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
	<!-- 使用annotation定義事務 -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />	
	
	<!-- SpringContext Holder -->
	<bean id="springContextHolder" class="com.sso.sys.SpringContextHolder" lazy-init="false"/>
</beans>

下面這個是重點shiro的spring配置:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd"
	default-lazy-init="false">
	<!-- shiroDbRealm -->
	<bean id="shiroDbRealm" class="com.sso.shiro.RealmManager"></bean>
	<!-- 安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="shiroDbRealm" />
		<property name="sessionManager" ref="sessionManager" />
		<!-- 緩存管理器 -->
		<property name="cacheManager" ref="shiroCacheManager" />
	</bean>
	<!-- apache默認的session管理定時器 -->
	<bean name="sessionValidationScheduler " class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
	</bean>
	<bean id="sessionManager" class="com.sso.shiro.MySessionManager">
		<!-- 超時時間 -->
		<property name="globalSessionTimeout" value="${sessionTimeout}" /><!-- 這是shrio管理session的超時時間 -->
		<property name="sessionDAO" ref="shiroSessionDao" /><!-- 這裏對session的CURD操作 -->
		<property name="sessionIdCookie" ref="sharesession" /><!-- shiro自己的cookie管理器 -->
		<!-- 啓動shiro自己的session檢查定時器 定時檢查失效的session 默認半小時執行一次-->
		<property name="sessionValidationSchedulerEnabled" value="true" />
	</bean>
	<bean id="sharesession" class="org.apache.shiro.web.servlet.SimpleCookie">
		<property name="name" value="${domain}" />
	</bean>
	<bean id="shiroSessionDao" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO" />
	<!-- 單機session -->
	<bean id="shiroCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
	<!-- 自定義的權限加載機制 -->
	<bean id="chainDefinitionSectionMetaSource" class="com.sso.shiro.DefaultChainDefinitionsFactoryBean" />
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/gotoLoginView" />
		<property name="successUrl" value="/viewAllContacts.do" />
		<property name="unauthorizedUrl" value="/meiquanxian" />
		<property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />
		<property name="filters">
			<map>
				<entry key="perms">
					<bean class="com.sso.shiro.MyPermsAuthorizationFilter"/>
				</entry>
				<entry key="authc">
					<bean class="com.sso.shiro.MyFormAuthenticationFilter"/>
				</entry>
				<entry key="ws">
					<bean class="com.sso.shiro.WebServiceAuthorizationFilter"/>
				</entry>
			</map>
		</property>

	</bean>
	<!-- 起效權限註解,這個很少在web項目中用到,一般是控制url的訪問,不是在controller中聲明權限註解 -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>

從上到下依次給大家講解。

 

1、shiroDbRealm:這是一個自定義的realm,realm的作用我的理解就是用來給用戶登陸和設置權限的。具體講解請看第二章。

2、securityManager:安全管理器,從它的注入屬性來看,他管理着用戶的realm、session、cache,我的理解是可以將他看作是一箇中心,所有的操作都要經過它的調度。

 

3、sessionValidationScheduler:他是shiro自己的一個session管理器,從源碼可以看出它其實就是一個線程,這個東西不需要手動注入,這裏列出來是因爲我覺得默認30分鐘一次的刷新頻率太低了,當初想通過這種方式來改掉他的默認時間,大家從我只寫了一行代碼可以看出結果當然是失敗的。

4、sessionManager:這是對session所有操作的一個管理類。

5、sharsession:用來設置當前會話的cookie設置,屬性包括cookie所的屬性。

6、shiroCacheMnanager:chche管理器,這裏面是一個單機版的管理器,如果是集羣據說要重寫sessionDAO這個組件,具體的沒有研究過,過後再研究一下。

7、chainDefinitionSectionMetaSource:這個是我自己寫資源加載器,大家都知道shiro的標準配置方式是在xml裏面配置資源地址而在xml裏面配置地址會有很多的不便,經過研究最終寫出了通過項目啓動時訪問數據庫來加載地址的方式。具體的實現方式在後面會講到。

8、shiroFilter:這是shiro攔截器的入口位置,用來初始化所有需要的組件及參數。

9、lifecycleBeanPostProcessor:說實話不知道這是幹嘛的,看註釋意思是使用註解來控制權限。

下面是web.xml的一個設置:

 

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
  <display-name>member</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:/applicationContext*.xml</param-value>
  </context-param>
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/springmvc-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

前半部分是對編碼的一個設置,中間部分是shiro的設置,在這裏要說一下shiro攔截器的加載方法與普通攔截器不一樣具體原理沒明白但有一點filter-name必須要與xml裏面定義的bean id一樣否則會報錯。在shiro的後面就是spring自己的配置了跟正常的一樣沒什麼好說的。

 

在這要說一句,shiro裏面接管了session默認的應該是30分鐘,如果在這裏設置的話應該就不起作用了需要在shiro的配置項裏面去設置globalSessionTimeOut。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章