自定义注解
4个原注解:最基本的用来标记注解的注解
@Documented:当前程序如果生成javadoc文档是否将当前注解添加进去
@Target:当前注解的标记范围
- ElementType.ANNONTATION_TYPE:当前注解可以标记其他注解
- ElementType.CONSTRUCTOR:标记构造方法
- ElementType.FIELD:标记成员变量
- ElementType.LOCAL_VARIABLE:标记局部变量
- ElementType.METHOD:标记方法
- ElementType.PACKAGE:标记包
- ElementType.PARAMETER:标记方法形式参数
- ElementType.TYPE:标记类、接口、内部类
@Retention:当前注解有效范围
- RetentionPolicy.SOURCE:当前注解只在源码中有效,编译后丢失
- RetentionPolicy.CLASS:当前注解只在编译文件中有效,运行时丢失
- RetentionPolicy.RUNTIME:当前注解在运行时有效 ,如果注解需配置反射使用,则必需选择这个范围
注解的方法
声明格式:返回值类型 方法名() [default 默认返回值];
注意:
- 注解中方法的名字如果为value,在使用注解时可以省略方法名
- 如果一个方法没有设置默认返回值 ,则在使用注解时必需设置这个方法的返回值
- 如果一个注解有多个方法,在使用注解时不能省略value
- 注解的返回值可以是一个数组 ,在使用时按以下规范 @xxx(method={xx,xx,xx})
- 如果只要给数组一个值的话,则可以省略大括号
实现自定义注解
1.自定义注解
import java.lang.annotation.*; @Documented @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface IsLogin { boolean mustLongin() default false; }
2.切面类
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; /** * 切面类 */ @Aspect public class LoginAop { /** * 环绕增强:判断当前的目标方法是作用于登录环境 * @return */ // 添加IsLogin注解的方法都会被环绕增强 @Around("@annotation(IsLogin)") public Object isLogin(ProceedingJoinPoint joinPoint){ try { System.out.println("在目标方法前执行..."); //执行目标方法 Object proceed = joinPoint.proceed(); // 放行,实际调用的是addCart方法 System.out.println("在目标方法后执行..."); return proceed; } catch (Throwable throwable) { throwable.printStackTrace(); } return null; } }
3.使用自定义注解
import com.qa.aop.IsLogin; import org.springframework.stereotype.Controller; @Controller @RequestMapping("/Car") public class CartController { @RequestMapping("/add") @IsLogin public String addCart(ShopCart shopCar,User user){ System.out.println("添加购物车..."); return null; } }
切记:使用到该自定义注解的工程,在启动类中通过@Bean方式,把切面类让spring管理起来
// @Bean 把方法的返回值让spring管理起来 @Bean public LoginAop getLoginAop(){ return new LoginAop(); }