元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
/**
* 水果供应者注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
/**
* 供应商编号
* @return
*/
public int id() default -1;
/**
* 供应商名称
* @return
*/
public String name() default "";
/**
* 供应商地址
* @return
*/
public String address() default "";
}
#3、注解的使用
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{
String hello () default "hello";
String world();
}
public class MyTest
{
@MyAnnotation(hello = "Hello,Beijing",world = "Hello,world")
public void output() {
System.out.println("method output is running ");
}
}
public class MyReflection
{
public static void main(String[] args) throws Exception
{
//1.获得要调用的类
Class myTestClass = MyTest.class;
//2.获得要调用的方法,output是要调用的方法名字,new Class[]{}为所需要的参数。空则不是这种
Method method = myTestClass.getMethod("output", new Class[]{});
//3.方法中是否有类型为MyAnnotation的注解
if (method.isAnnotationPresent(MyAnnotation.class))
{
//4.获得注解
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
//5.调用注解的内容
System.out.println(annotation.hello());
System.out.println(annotation.world());
}
System.out.println("----------------------------------");
// 获得所有注解。必须是runtime类型的
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations)
{
// 遍历所有注解的名字
System.out.println(annotation.annotationType().getName());
}
}
}
权限注解 用于检查权限 规定访问权限
对目标方法进行标注@Permission(Const.ADMIN_NAME)
相当于shiro的@RequiresPermissions("/mgr/role_assign") ,指定某方法需要指定的资源访问权限【资源】/mgr/role_assign
@Permission不需要写资源参数。他的参数代表指定角色的权限【任意1即可】。
本质:无参-判断hasPermission 有参-判断hasAnyRoles
@Order(200) 控制AOP顺序
1.将实现类加入spring管理
2.编写切面类 PermissionAop
3.定义可以定义可重用的切点@Pointcut
4.在需要执行的切面的方法上即可【这里是无参节点】
当需要AOP操作时,相关注解内传入刚才定义的方法就可以。
@Pointcut(value = "@annotation(cn.stylefeng.guns.core.common.annotion.Permission)")
private void cutPermission() {}
@Around("cutPermission()")
public Object doPermission(ProceedingJoinPoint point) throws Throwable {
//获得注释方法签名【方法名+形参】
MethodSignature ms = (MethodSignature)
//获得方法
point.getSignature();
Method method = ms.getMethod();
//获取方法上的注释
Permission permission = method.getAnnotation(Permission.class);
//获取注释的值
Object[] permissions = permission.value();
if (permissions.length == 0) {
//检查全体角色-用户是否拥有当前请求的servlet的权限
boolean result = check.checkAll();
if (result) {
return point.proceed();
} else {
throw new NoPermissionException();
}
} else {
//检查指定角色
boolean result = check.check(permissions);
if (result) {
return point.proceed();
} else {
throw new NoPermissionException();
}
}
}
5.有参案例:
有参切点定义:
@Pointcut("execution(* com.ooo.Pointcut.OperatorTest.add222(..))"+"&& args(food,name)")
public void function(String food,String name){}
@Before("function(food,name)")
public void beforeMethod(JoinPoint jp,String food,String name){
String methodName = jp.getSignature().getName();
System.out.println("【前置通知】获取参数food:"+food);
System.out.println("【前置通知】获取参数name:"+name);
System.out.println("【前置通知】the method 【" + methodName + "】 begins with " + Arrays.asList(jp.getArgs()));
}
public interface PermissionCheckService {
/**
* 检查当前登录用户是否拥有指定的角色访问当
*/
boolean check(Object[] permissions);
/**
* 检查当前登录用户是否拥有当前请求的servlet的权限
*/
boolean checkAll();
}
获取request
获取user
获取requestURI
只判断前2/段的权限
@Override
public boolean checkAll() {
HttpServletRequest request = HttpContext.getRequest();
ShiroUser user = ShiroKit.getUser();
if (null == user) {
return false;
}
String requestURI = request.getRequestURI().replaceFirst(ConfigListener.getConf().get("contextPath"), "");
String[] str = requestURI.split("/");
if (str.length > 3) {
requestURI = "/" + str[1] + "/" + str[2];
}
if (ShiroKit.hasPermission(requestURI)) {
return true;
}
return false;
}
1.request.getContextPath()–>/news
2.request.getServletPath()–>/main/list.jsp
3.request.getRequestURI() -->/news/main/list.jsp