自定义注解

自定义注解目录 一 注解的概念 Java 注解分类 JDK 基本注解 JDK 元注解 如何自定义注解 二 自定义注解 编写两个自定义注解类 interface 注解修饰符 使用注解 StudentContr 测试获取注解中的值 Demo1 测试结果 三

大家好,我是讯享网,很高兴认识大家。

目录

一,注解的概念

Java注解分类

JDK基本注解

JDK元注解

如何自定义注解?

二,自定义注解

编写两个自定义注解类

@interface 注解修饰符

使用注解

StudentController

测试获取注解中的值

Demo1

测试结果

三,Aop应用自定义注解

自定义注解日志的使用

 自定义注解类

使用注解的类

切面类

测试类


一,注解的概念

Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。 注解相关类都包含在java.lang.annotation包中。

Java注解分类

JDK基本注解
JDK元注解
自定义注解

JDK基本注解


讯享网

JDK元注解

@Retention:定义注解的保留策略
@Retention(RetentionPolicy.SOURCE)             //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS)              //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME)            //注解会在class字节码文件中存在,在运行时可以通过反射获取到

@Target:指定被修饰的Annotation可以放置的位置(被修饰的目标)
@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}),也就是此注解可以在方法和类上面使用

@Inherited:指定被修饰的Annotation将具有继承性

@Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档.

如何自定义注解?

使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是:
   Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型,
   而且我们还可以使用default关键字为这个成员变量设定默认值;

二,自定义注解

编写两个自定义注解类

@interface 注解修饰符

如果属性是value的话,可以省略value=;如果是其他,则不可以省略。

MyAnnotation1

package com.zking.ssm.annotation; import javax.swing.*; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; / * @author ljj * @site www.xiaomage.com * @company * @create  2022-11-03 2:52 * * 自定义注解类 */ @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})//(接口|类,方法,属性)决定此注解可以修饰什么内容 @Retention(RetentionPolicy.RUNTIME) //注解修饰符 @interface public @interface MyAnnotation1 { //注解中属性 //如果属性是value的话,可以省略value=,其他的属性不行 public String value() default "可以修饰属性,类,方法"; public String desc() default "可以修饰属性,类,方法"; } 

讯享网

MyAnnotation2

讯享网package com.zking.ssm.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; / * @author ljj * @site www.xiaomage.com * @company * @create  2022-11-03 2:52 * * 放在参数中的注解 ElementType.PARAMETER */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) //注解修饰符 @interface public @interface MyAnnotation2 { //注解中属性 //如果属性是value的话,可以省略value=,其他的属性不行 public String value() default "可以修饰属性,类,方法"; public String desc() default "可以修饰属性,类,方法"; } 

使用注解

StudentController

 此类用作于使用自定义的注解

package com.zking.ssm.annotation; / * @author ljj * @site www.xiaomage.com * @company * @create  2022-11-03 3:01 * * 使用注解 */ @MyAnnotation1(desc = "标记在类上面") public class StudentController { @MyAnnotation1("标记在属性id上面") private String id; @MyAnnotation1("标记在name上面") private String name; @MyAnnotation1 public void test1(@MyAnnotation2("用来修饰id参数") String id,@MyAnnotation2("用来修饰name参数") String name){ System.out.println("测试"); } } 

测试获取注解中的值

Demo1

讯享网package com.zking.ssm.annotation.demo; import com.zking.ssm.annotation.MyAnnotation1; import com.zking.ssm.annotation.MyAnnotation2; import com.zking.ssm.annotation.StudentController; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; / * @author ljj * @site www.xiaomage.com * @company * @create  2022-11-03 3:44 * * 目标 * 1:获取studentControler 类上自定义注解 中的内容 * 2:获取studentControler 方法上自定义注解 中的内容 * 3:获取studentControler 属性上自定义注解 中的内容 */ public class Demo1 { public static void main(String[] args) throws Exception { MyAnnotation1 annotation = StudentController.class.getAnnotation(MyAnnotation1.class); //获取类上自定义注解中的内容 System.out.println(annotation.value()); System.out.println(annotation.desc()); //获取属性上自定义注解中的内容 Field id = StudentController.class.getDeclaredField("id"); Field name = StudentController.class.getDeclaredField("name"); System.out.println(id.getAnnotation(MyAnnotation1.class).value()); System.out.println(name.getAnnotation(MyAnnotation1.class).value()); //获取方法上自定义注解中的内容 Method m1 = StudentController.class.getDeclaredMethod("test1", String.class, String.class); System.out.println(m1.getAnnotation(MyAnnotation1.class).value()); //获取参数上自定义注解中的内容 for (Parameter p : m1.getParameters()) { System.out.println(p.getAnnotation(MyAnnotation2.class).value()); } } } 

测试结果

三,Aop应用自定义注解

自定义注解日志的使用

自定义注解的介入,可以在使用注解的地方,才触发aop切面

 自定义注解类

MyLog

package com.zking.ssm.annotation.aop; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; / * @author ljj * @site www.xiaomage.com * @company * @create  2022-11-03 19:38 */ @Target(ElementType.METHOD)//可以用作于方法中 @Retention(RetentionPolicy.RUNTIME)//运行时使用 public @interface MyLog { String desc(); } 

使用注解的类

DemoController

讯享网package com.zking.ssm.annotation.aop; import org.springframework.stereotype.Controller; / * @author ljj * @site www.xiaomage.com * @company * @create  2022-11-03 19:41 */ @Controller public class DemoController { @MyLog(desc="这是一个测试类的方法") public void test(){ System.out.println("测试方法"); } } 

切面类

MyLogAspect 

package com.zking.ssm.annotation.aop; import org.aspectj.lang.JoinPoint; 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; @Component @Aspect public class MyLogAspect { private static final Logger logger = LoggerFactory.getLogger(MyLogAspect.class); / * 只要用到了com.javaxl.p2.annotation.springAop.MyLog这个注解的,就是目标类 */ @Pointcut("@annotation(com.zking.ssm.annotation.aop.MyLog)") private void MyValid() { } @Before("MyValid()") public void before(JoinPoint joinPoint) { // JoinPoint // 可以获取到目标对象,目标方法,传递参数 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); logger.debug("[" + signature.getName() + " : start.....]"); System.out.println("[" + signature.getName() + " : start.....]"); MyLog myLog = signature.getMethod().getAnnotation(MyLog.class); logger.debug("【目标对象方法被调用时候产生的日志,记录到日志表中】:"+myLog.desc()); System.out.println("【目标对象方法被调用时候产生的日志,记录到日志表中】:" + myLog.desc()); } }

测试类

AnnotationTest 

讯享网package com.zking.shiro; import com.zking.ssm.annotation.aop.DemoController; import com.zking.ssm.annotation.demo.Demo1; import com.zking.ssm.biz.ClazzBiz; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; / * @author小李飞刀 * @site www.javaxl.com * @company xxx公司 * @create  2022-10-26 15:29 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:applicationContext.xml"}) public class AnnotationTest { @Autowired private DemoController demoController; @Test public void test1(){ demoController.test(); } } 

两个断点,一个在切面类中,一个在注解使用类中

 执行测试类中的方法

Debug第一次到达的地方 进入@Before 前置通知中

 进入下一个断点

小讯
上一篇 2025-03-14 19:31
下一篇 2025-02-11 20:05

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/62912.html