自定义注解@interface

本文主要介绍自定义注解在aop或者拦截器中通过反射获取注解的属性,主要运用于

  1. 权限的控制

1.java元注解

Retention注解

Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值: 
1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略 
2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略 
3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.

下面示例中, @Retention(RetentionPolicy.RUNTIME)注解表明 Test_Retention注解将会由虚拟机保留,以便它可以在运行时通过反射读取.

Documented 注解

Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中.(个人观点:不是重点,了解即可。勿喷)

Target注解

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。 
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方) 
取值(ElementType)有:

1.CONSTRUCTOR:用于描述构造器 
2.FIELD:用于描述域 
3.LOCAL_VARIABLE:用于描述局部变量 
4.METHOD:用于描述方法 
5.PACKAGE:用于描述包 
6.PARAMETER:用于描述参数 
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

Inherited 注解

这是一个稍微复杂的注解类型. 它指明被注解的类会自动继承. 更具体地说,如果定义注解时使用了 @Inherited 标记,然后用定义的注解来标注另一个父类, 父类又有一个子类(subclass),则父类的所有属性将被继承到它的子类中.

自定义注解:
 

package com.mor.shiro.annotation;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import java.lang.annotation.*;

/**
 * @author zht
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
//最高优先级
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RoleControl {
    String value() default "user";
}

接口:

@RoleControl("ADMIN")
@Controller
public class LoginController {

    @RoleControl("USER")
    @RequestMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse resp) {
        return "";
    }
}

切面 :(通过反射获取控制器上的注解 )

@Component
@Aspect
public class RoleControlAspect {

    /**类上注解情形 */
//  @Pointcut("@within(net.xby1993.springmvc.annotation.RoleControl)")
    @Pointcut("execution(* com.mor.shiro.controller.*.*(..)) && @within(com.mor.shiro.annotation.RoleControl)")
    public void aspect(){

    }
    /**方法上注解情形 */
    @Pointcut("execution(* com.mor.shiro.controller.*.*(..)) && @annotation(com.mor.shiro.annotation.RoleControl)")
    public void aspect2(){

    }
    /**aop实际拦截两种情形*/
    @Around("aspect() || aspect2()")
    public Object doBefore(ProceedingJoinPoint point) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session=request.getSession();
        Object target = point.getTarget();
        String method = point.getSignature().getName();
        System.out.println(method);
        Class classz = target.getClass();
        Method m = ((MethodSignature) point.getSignature()).getMethod();
        try {
            if (classz!=null && m != null ) {
                boolean isClzAnnotation= classz.isAnnotationPresent(RoleControl.class);

                boolean isMethondAnnotation=m.isAnnotationPresent(RoleControl.class);
                RoleControl rc=null;
                //如果方法和类声明中同时存在这个注解,那么方法中的会覆盖类中的设定。
                if(isClzAnnotation){
                    rc=classz.getAnnotation(RoleControl.class);
                    if(isMethondAnnotation){
                        rc=m.getAnnotation(RoleControl.class);
                    }
                }
                String value=rc.value();
                System.out.println(value);
                //进行角色访问的权限控制,只有当前用户是需要的角色才予以访问。
                boolean isEquals=true;
                if(isEquals){
                    try {
                        return point.proceed();
                    } catch (Throwable e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

            }
        }catch(Exception e){

        }
        return null;
    }
}

 

你可能感兴趣的:(自定义注解@interface)