目录
一,注解的概念
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 前置通知中

进入下一个断点

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