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 "";
}
写得有点快,有点粗糙,希望大家多提意见