目录
1.注解的概念
1.1 什么是注解
1.2 java注解分类
1.3 JDK基本注解
1.4 JDK元注解
2.自定义注解
2.1 自定义注解的组成
2.2 如何自定义注解
2.3 案例
2.3.1 简单了解基本属性
2.3.2 获取类与方法上的注解值
2.3.3 获取类属性上的注解属性值
2.3.4 获取参数修饰注解对应的属性值
3.aop的应用自定义注解
1.注解的概念
1.1 什么是注解
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
1.2 java注解分类
JDK基本注解
JDK元注解
自定义注解
1.3 JDK基本注解
@Override
重写@SuppressWarnings(value = "unchecked")
压制编辑器警告
1.4 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工具提取成文档.
2.自定义注解
2.1 自定义注解的组成
注解分类(根据Annotation是否包含成员变量,可以把Annotation分为两类):
标记Annotation:
没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息元数据Annotation:
包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据;
2.2 如何自定义注解
使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是:
Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型,
而且我们还可以使用default关键字为这个成员变量设定默认值;
2.3 案例
2.3.1 简单了解基本属性
假设这是我们写的一个注解类
我们使用它时就会报错
其根本原因是注解类上面的Target,
METHOD 注解只能在方法上使用
TYPE 注解只能在类上使用
FIELD 注解只能在属性上使用
我们改成TYPE就可以啦
不报错啦
如果想用多个
可以写多个tagar
代码:
//1.只能用于类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
//2.只能用于属性
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
//3.只能用于方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
//4.类,属性,方法都可以用
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
给注解写一个属性
若没有加注解的属性就会报错
写上注解的属性就可以不报错了,value这个属性可以默认不写,其他的属性就不能了
还可以默认注解的属性
这样也不会报错啦
2.3.2 获取类与方法上的注解值
直接运行我们就会报错
原因是注解上的source,将它改为runtime运行时可见
结果为(获取到啦):
测试的代码:
package com.zking.ssm.annaction.dome;
import com.zking.ssm.annaction.MyAnnaction1;
import com.zking.ssm.annaction.MyAnnaction2;
import com.zking.ssm.annaction.RuojuanController;
/**
* @author ruojuan
* @site www.ruojuan.com
* @company 玉渊工作室
* @create 2022年10月27日 14:21
**/
public class Dome1 {
public static void main(String[] args) {
//获取类上的注解
MyAnnaction1 annaction = RuojuanController.class.getAnnotation(MyAnnaction1.class);
System.out.println(annaction.value());
System.out.println(annaction.desc());
}
}
注解的代码:
package com.zking.ssm.annaction;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author ruojuan
* @site www.ruojuan.com
* @company 玉渊工作室
* @create 2022年10月27日 11:14
**/
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnaction1 {
//指的是注解中的属性
public String value() default "可以修饰方法,属性,类";
public String desc() default "可以修饰方法,属性,类";
}
2.3.3 获取类属性上的注解属性值
代码:
package com.zking.ssm.annaction.dome;
import com.zking.ssm.annaction.MyAnnaction1;
import com.zking.ssm.annaction.MyAnnaction2;
import com.zking.ssm.annaction.RuojuanController;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* @author ruojuan
* @site www.ruojuan.com
* @company 玉渊工作室
* @create 2022年10月27日 14:21
**/
public class Dome1 {
public static void main(String[] args) throws Exception {
//获取属性上的
Field id = RuojuanController.class.getDeclaredField("id");
Field name = RuojuanController.class.getDeclaredField("name");
System.out.println(id.getAnnotation(MyAnnaction1.class).value());
System.out.println(name.getAnnotation(MyAnnaction1.class).value());
}
}
2.3.4 获取参数修饰注解对应的方法值
效果:
代码:
package com.zking.ssm.annaction.dome;
import com.zking.ssm.annaction.MyAnnaction1;
import com.zking.ssm.annaction.MyAnnaction2;
import com.zking.ssm.annaction.RuojuanController;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author ruojuan
* @site www.ruojuan.com
* @company 玉渊工作室
* @create 2022年10月27日 14:21
**/
public class Dome1 {
public static void main(String[] args) throws Exception {
//获取方法上的
Method me1 = RuojuanController.class.getDeclaredMethod("test", long.class, String.class);
System.out.println(me1.getAnnotation(MyAnnaction1.class).value());
}
}
写一个专门用来修饰属性的
代码:
package com.zking.ssm.annaction;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author ruojuan
* @site www.ruojuan.com
* @company 玉渊工作室
* @create 2022年10月27日 11:14
**/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnaction2 {
//指的是注解中的属性
public String value() default "可以修饰方法,属性,类";
public String desc() default "可以修饰方法,属性,类";
}
获取参数上的标识
代码:
package com.zking.ssm.annaction.dome;
import com.zking.ssm.annaction.MyAnnaction1;
import com.zking.ssm.annaction.MyAnnaction2;
import com.zking.ssm.annaction.RuojuanController;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* @author ruojuan
* @site www.ruojuan.com
* @company 玉渊工作室
* @create 2022年10月27日 14:21
**/
public class Dome1 {
public static void main(String[] args) throws Exception {
//获取方法上的
Method me1 = RuojuanController.class.getDeclaredMethod("test", long.class, String.class);
System.out.println(me1.getAnnotation(MyAnnaction1.class).value());
//获取参数上的标识
for(Parameter p:me1.getParameters()){
System.out.println(p.getAnnotation(MyAnnaction2.class).value());
}
}
}
3.aop的应用自定义注解
自定义注解
package com.zking.annotation.aop;
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();
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1. 注解式开发 -->
<!-- 注解驱动 -->
<context:annotation-config/>
<!-- 用注解方式注入bean,并指定查找范围:com.javaxl.ssh2及子子孙孙包-->
<context:component-scan base-package="com.zking"/>
<!--开启动态代理-->
<aop:aspectj-autoproxy />
</beans>
应用注解
package com.zking.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.annotation.aop.MyLog)")
private void MyValid() {
}
@Before("MyValid()")
public void before(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());
}
}
package com.zking.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.annotation.aop.MyLog)")
private void MyValid() {
}
@Before("MyValid()")
public void before(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());
}
}
package com.zking.annotation.aop;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class BaseTestCase {
}
package com.zking.annotation.aop;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class LogControllerTest extends BaseTestCase {
@Autowired
private LogController logController;
@Test
public void testLogAspect(){
logController.testLogAspect();
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zking</groupId>
<artifactId>selenium280</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>selenium280 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
<!--添加jar包依赖-->
<!--1.spring 5.0.2.RELEASE相关-->
<spring.version>5.0.2.RELEASE</spring.version>
<!--2.mybatis相关-->
<mybatis.version>3.4.5</mybatis.version>
<!--mysql-->
<mysql.version>5.1.44</mysql.version>
<!--pagehelper分页jar依赖-->
<pagehelper.version>5.1.2</pagehelper.version>
<!--mybatis与spring集成jar依赖-->
<mybatis.spring.version>1.3.1</mybatis.spring.version>
<!--3.dbcp2连接池相关 druid-->
<commons.dbcp2.version>2.1.1</commons.dbcp2.version>
<commons.pool2.version>2.4.3</commons.pool2.version>
<!--4.log日志相关-->
<log4j2.version>2.9.1</log4j2.version>
<log4j2.disruptor.version>3.2.0</log4j2.disruptor.version>
<slf4j.version>1.7.13</slf4j.version>
<!--5.其他-->
<junit.version>4.12</junit.version>
<servlet.version>4.0.0</servlet.version>
<lombok.version>1.18.2</lombok.version>
</properties>
<dependencies>
<!--1.spring相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--2.mybatis相关-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--pagehelper分页插件jar包依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!--mybatis与spring集成jar包依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!--3.dbcp2连接池相关-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${commons.dbcp2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${commons.pool2.version}</version>
</dependency>
<!--4.log日志相关依赖-->
<!-- log4j2日志相关依赖 -->
<!-- log配置:Log4j2 + Slf4j -->
<!-- slf4j核心包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<!--核心log4j2jar包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!--用于与slf4j保持桥接-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!--web工程需要包含log4j-web,非web工程不需要-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j2.version}</version>
<scope>runtime</scope>
</dependency>
<!--需要使用log4j2的AsyncLogger需要包含disruptor-->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>${log4j2.disruptor.version}</version>
</dependency>
<!--5.其他-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- jsp文件中c标签的使用-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>selenium280</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>