本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用。
java内置注解
1、@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
2、@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
RetentionPolicy.SOURCE 注解将被编译器丢弃
RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
一、注解类源码
- /**
- * 方 法访问角色注解
- */
- @Target (ElementType.METHOD)
- @Retention (RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- public @interface VisitorRole {
- String value();
- }
/**
* 方法访问角色注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface VisitorRole {
String value();
}
二、Person类的源码。该类使用了自定义注解。
- @Component ( "person" ) //此处通过注解的方式定义受管Bean
- public class Person {
- private String userId = "cjm" ;
- private String userName = "jumin.chen" ;
- @VisitorRole ( "ADMIN" ) //自定 义注解的使用。只有具有ADMIN角色才能调用本方法。
- public String say(){
- return "I'm " + userName;
- }
- }
@Component("person") //此处通过注解的方式定义受管Bean
public class Person {
private String userId = "cjm";
private String userName = "jumin.chen";
@VisitorRole("ADMIN") //自定义注解的使用。只有具有ADMIN角色才能调用本方法。
public String say(){
return "I'm " + userName;
}
}
三、通过环绕通知对方法进行拦截,只有当角色匹配时,才能执行方法。
- /**
- * 环 绕通知:在类方法调用前,先判断角色是否匹配。
- */
- @Component ( "visitorRoleAdvice" )
- public class VisitorRoleAdvice implements MethodInterceptor {
- public Object invoke(MethodInvocation invocation) throws Throwable {
- if (invocation.getMethod().isAnnotationPresent(VisitorRole. class )){ //有指 定注解
- String role = null ;
- Annotation annotation = invocation.getMethod().getAnnotation(VisitorRole.class ); //获取指 定注解
- if (annotation!= null ){
- role = ((VisitorRole)annotation).value(); //从注解中获取角色
- }
- if ( "ADMIN" .equals(role)){
- return invocation.proceed(); //角色匹配,继续执行方法
- }else {
- System.out.println("没有角色权限!" );
- return null ;
- }
- }else { //类方法没有 自定义注解,直接执行该方法
- return invocation.proceed();
- }
- }
- }
/**
* 环绕通知:在类方法调用前,先判断角色是否匹配。
*/
@Component("visitorRoleAdvice")
public class VisitorRoleAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
if(invocation.getMethod().isAnnotationPresent(VisitorRole.class)){ //有指定注解
String role = null;
Annotation annotation = invocation.getMethod().getAnnotation(VisitorRole.class); //获取指定注解
if(annotation!=null){
role = ((VisitorRole)annotation).value(); //从注解中获取角色
}
if("ADMIN".equals(role)){
return invocation.proceed(); //角色匹配,继续执行方法
}else{
System.out.println("没有角色权限!");
return null;
}
}else{ //类方法没有自定义注解,直接执行该方法
return invocation.proceed();
}
}
}
四、Spring配置
- <!-- 声明通过注解定义bean,同时也通过注解自动注入 -->
- < context:component-scan base-package = "com.cjm" annotation-config = "true" />
- < bean class = "org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
- < bean id = "nameMatchMethodPointcutAdvisor" class = "org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
- < property name = "advice" ref = "visitorRoleAdvice" />
- < property name = "mappedNames" >
- < list >
- < value > say </ value >
- </ list >
- </ property >
- </ bean >