1. 程式人生 > >springAOP與自定義註解實現細粒度許可權控制管理

springAOP與自定義註解實現細粒度許可權控制管理

IOC與AOP無疑是spring的核心,提供了非常強大的功能,這兩個思想為我們開發帶來了巨大的方便。

這裡我們aop簡單實現一些許可權控制,用到的aop提供的環繞通知,至於spring提供了那些通知,大家可以自行百度。

<bean id="privilegeAspect" class="com.privilege.PrivilegeAspect"></bean>
    <aop:config>
        <!-- 
                              切入點表示式,確認目標類 
            com.service.impl包中的所有類中的所有方法
        -->
        <aop:pointcut expression="execution(* com.service.impl.*.*(..))" id="perform"/>
        <!-- ref指向的物件就是切面 -->
        <aop:aspect ref="privilegeAspect">
            <!-- 環繞通知 -->
            <aop:around method="isAccessMethod" pointcut-ref="perform"/>
        </aop:aspect>
    </aop:config>

可以直接這樣配環繞通知,然後自行實現具體類的具體方法。

我這裡使用spring提供的一個介面,已經幫我們實現好了,只需要配置好,實現他就可以了,可以更好的使用一些方便的方法

<bean id="privilegeInterceptor" class="com.interceptor.PrivilegeInterceptor"></bean>
	<bean
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames">
			<list>
				<value>*Service</value>
			</list>
		</property>
		<property name="interceptorNames">
			<list>
				<value><span style="font-family: Arial, Helvetica, sans-serif;">privilegeInterceptor</span></value>
			</list>
		</property>
	</bean>	
這裡的意思攔截所有service類裡的方法,然後執行interceptorNames的攔截器,可以配置多個攔截器,按順序執行
package com.interceptor;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;


/**
 * @author landong.sun
 *
 */
public class PrivilegeInterceptor implements MethodInterceptor{
	
	@Autowired
	SessionProvider sessionProvider;

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		
		Method method = invocation.getMethod();//獲取被攔截的方法
		Object[] arguments = invocation.getArguments();//獲取攔截方法的引數
		PrivilegeInfo privilegeInfo = AnnotationUtils.findAnnotation(method, PrivilegeInfo.class);//根據方法找到註解,這個註解是我們自定義的註解,下面會講
		if(privilegeInfo!=null) {
			String value = (String) AnnotationUtils.getAnnotationAttributes(privilegeInfo).get("value");//獲取許可權值
			boolean isAccessed = false;
	        MenuCondition isPrivilege = new MenuCondition();//這是一個許可權類
	        //從session中獲取許可權
	        for (MenuCondition privilege : privileges) {
	            /*
	             * 如果目標方法沒有使用PrivilegeInfo註解,則解析出來的許可權字串就為空字串
	             * 則預設使用者擁有這個許可權
	             */
	            if ("".equals(methodAccess)) {
	                isAccessed = true;
	                break;
	            }
	            /*
	             * 使用者原有許可權列表中有的許可權與目標方法上PrivilegeInfo註解配置的許可權進行匹配
	             */
	            String truePrivikey = privilege.getlPrivyKey()+"";
	            if (truePrivikey!= null && 
	            		StringUtils.equalsIgnoreCase(methodAccess, truePrivikey)) {
	                isAccessed = true;
	                isPrivilege = privilege;
	                break;
	            }
	        }
	        /*
	         * 3.如果使用者擁有許可權,則呼叫目標方法 ,如果沒有,則不呼叫目標方法,只給出提示
	         */
	        if (isAccessed) {
	        	/*
	             * 特殊,某些許可權需要做特殊處理
	             * 比如使用者資訊許可權,在方法執行完畢返回的時候,要將電話號碼與郵箱抹除
	             */
	        	//環繞通知前置特殊處理
	        	this.beforeReslove();
	            Object proceed = invocation.proceed();//呼叫目標方法
	            //環繞通知後置特殊處理
	            proceed =  this.afterReslove();
	            return proceed;
	            
	        } else{
	        	ResultUtils.throwExcepion(ResultUtils.createFail(Config.FBD_MESSAGE, 301, null));
	        }
				
		return null;
	}	

}

自定義註解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrivilegeInfo {

	String value() default "";
}


寫得有點快,有點粗糙,希望大家多提意見