springAOP與自定義註解實現細粒度許可權控制管理
阿新 • • 發佈:2018-12-24
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提供的一個介面,已經幫我們實現好了,只需要配置好,實現他就可以了,可以更好的使用一些方便的方法
這裡的意思攔截所有service類裡的方法,然後執行interceptorNames的攔截器,可以配置多個攔截器,按順序執行<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>
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 "";
}
寫得有點快,有點粗糙,希望大家多提意見