目录
4.2 @Target:指定被修饰的Annotation可以放置的位置(被修饰的目标)
4.3 @Inherited:指定被修饰的Annotation将具有继承性
4.4 @Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档.
8.1 通过动态注解 spring aop方式 来做一个日志记录
Java注解是附加在代码中的一些元信息,用于一些工具在编译、
运行时进行解析和使用,起到说明、配置的功能。注解相关类都包含在java.lang.annotation包中。
2.1 JDK基本注解
2.2 JDK元注解
2.3 自定义注解
3.1 @Override
重写
3.2 @Deprecated
已过时
3.3 @SuppressWarnings(value = "unchecked")
压制编辑器警告
元注解用于修饰其他的注解(纪委:管干部的干部)
@Retention(RetentionPolicy.SOURCE) // 注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target(ElementType.TYPE) // 接口、类
@Target(ElementType.FIELD) // 属性
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 方法参数
@Target(ElementType.CONSTRUCTOR) // 构造函数
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE) // 注解
@Target(ElementType.PACKAGE) // 包
@Target({ElementType.METHOD, ElementType.TYPE}),也就是此注解可以在方法和类上面使用
根据Annotation是否包含成员变量,可以把Annotation分为两类:
没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息
包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据;
使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是: Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型, 而且我们还可以使用default关键字为这个成员变量设定默认值
例如:
- @Inherited
-
- @Retention(RetentionPolicy.RUNTIME)
-
- @Target({ElementType.METHOD, ElementType.TYPE})
-
- public @interface Tag {
-
- String name() default "该叫啥才好呢?";
-
-
- String description() default "这家伙很懒, 啥也没留下...";
-
- }
使用AnnotatedElement接口中的方法提取注解中的数据,像Class/Constructor/Field/Method/Package这些类都实现了AnnotatedElement接口
注:只有当定义Annotation时使用了@Retention(RetentionPolicy.RUNTIME)修饰,
JVM才会在装载class文件时提取保存在class文件中的Annotation,该Annotation才会在运行时可见,这样我们才能够解析
Demo1
- package com.zking.ssm.annotation.p1;
-
-
- @MyAnnotation1(name = "abc")
- public class Demo1 {
-
- @MyAnnotation1(name = "xyz")
- private Integer age;
-
- @MyAnnotation2(model = TranscationModel.Read)
- public void list() {
- System.out.println("list");
- }
-
- @MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})
- public void edit() {
- System.out.println("edit");
- }
-
-
- }
MyAnnotation1
- package com.zking.ssm.annotation.p1;
-
- import java.lang.annotation.*;
-
-
- @Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface MyAnnotation1 {
- String name();
- }
MyAnnotation2
- package com.zking.ssm.annotation.p1;
-
- import java.lang.annotation.*;
-
-
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface MyAnnotation2 {
- TranscationModel model() default TranscationModel.ReadWrite;
- }
MyAnnotation3
- package com.zking.ssm.annotation.p1;
-
- import java.lang.annotation.*;
-
-
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface MyAnnotation3 {
- TranscationModel[] models() default TranscationModel.ReadWrite;
- }
TranscationModel
- package com.zking.ssm.annotation.p1;
-
- public enum TranscationModel {
- Read, Write, ReadWrite
- }
创建一个类开始测试
- package com.zking.ssm.annotation.p2;
-
- import com.zking.ssm.annotation.p1.*;
-
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Arrays;
-
- public class Demo2 {
-
- public static void main(String[] args) throws Exception {
- //1.提供类上的注解
- //注意:元注解@Retention必须设置为RUNTIME
- MyAnnotation1 annotation = Demo1.class.getAnnotation(MyAnnotation1.class);
- System.out.println(annotation.name());
-
- }
- }
- package com.zking.ssm.annotation.p2;
-
- import com.zking.ssm.annotation.p1.*;
-
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Arrays;
-
- public class Demo2 {
-
- public static void main(String[] args) throws Exception {
-
- //获取属性上的注解
- Field age = Demo1.class.getDeclaredField("age");
- age.setAccessible(true);//授权
- System.out.println(age);
- MyAnnotation1 annotation = age.getAnnotation(MyAnnotation1.class);
- String name = annotation.name();
- System.out.println(name);
- }
- }
- package com.zking.ssm.annotation.p2;
-
- import com.zking.ssm.annotation.p1.*;
-
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Arrays;
-
- public class Demo2 {
-
- public static void main(String[] args) throws Exception {
-
- //获取方法上的注解
- Method method = Demo1.class.getMethod("list");
- System.out.println(method);
- MyAnnotation2 annotation2 = method.getAnnotation(MyAnnotation2.class);
- TranscationModel model = annotation2.model();
- System.out.println(model);
-
- //获取方法上的注解,数组
- Method method = Demo1.class.getMethod("edit");
- System.out.println(method);
- MyAnnotation3 annotation3 = method.getAnnotation(MyAnnotation3.class);
- TranscationModel[] models = annotation3.models();
- System.out.println(Arrays.toString(models));
-
- }
- }
提问spring aop是什么?
答:
1)连接点(JoinPoint):在程序执行过程中明确的点,列如:方法的调用,异常的抛出
2)目标:被代理(被通知)的对象,执行具体核心业务逻辑
3)通知:在某种特定的连接点上所执行的动作
4)代理:将通知应用到目标后所得到的对象叫做代理对象,只有完整的代理对象才具有AOP特性 适配器+切入点
Demo3
- package com.zking.ssm.annotation.p3;
-
- import org.springframework.stereotype.Component;
-
- @Component
- public class Demo3 {
-
- private Integer age;
-
- @MyLog(desc = "测试测试!!!")
- public void hello(String name) {
- System.out.println("hello:" + name);
- }
-
-
- //测试类调用这个方法不会出现日志
- public void add(int a,int b){
- System.out.println("add" + a + b);
- }
- }
MyLog
- package com.zking.ssm.annotation.p3;
-
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface MyLog {
- String desc();
- }
MyLogAspect(核心切面类)
- package com.zking.ssm.annotation.p3;
-
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.Signature;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.Pointcut;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Component;
- import java.lang.reflect.Method;
-
- @Component
- @Aspect
- public class MyLogAspect {
-
- private static final Logger log = LoggerFactory.getLogger(MyLogAspect.class);
-
- @Pointcut("@annotation(com.zking.ssm.annotation.p3.MyLog)")
- private void MyValid() {
- }
-
- @Before("MyValid()")
- public void before(JoinPoint joinPoint) {
- Signature signature = joinPoint.getSignature();
- MethodSignature methodSignature = (MethodSignature) signature;
- Method method = methodSignature.getMethod();
- MyLog annotation= method.getAnnotation(MyLog.class);
- log.debug(annotation.desc());
- log.debug("[" + joinPoint.getSignature().getName() + " : start.....]");
- }
- }
创建测试类 开始测试
- package com.zking.ssm.service.impl;
-
- import com.zking.ssm.annotation.p3.Demo3;
- import org.junit.Test;
-
- import javax.annotation.Resource;
-
- /**
- * @author 蒋明辉
- * @data 2022/9/25 22:33
- */
- public class Demo3Test extends BaseTest{
- //注入
- @Resource
- private Demo3 demo3;
-
- @Test
- public void Demo01(){
- demo3.hello("蒋明辉每天都很可爱");
-
- }
-
-
- }