自定义注解
一、简单介绍
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。 注解相关类都包含在java.lang.annotation包中。
1.0 java注解分类
JDK基本注解
JDK元注解
自定义注解
1.0.1 JDK基本注解
@Override
重写
@SuppressWarnings(value = “unchecked”)
压制编辑器警告
1.0.2 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工具提取成文档.
1.0.3 自定义注解
注解分类(根据Annotation是否包含成员变量,可以把Annotation分为两类):
标记Annotation:
没有成员变量的Annotation; 这种Annotation仅利用自身的存在与否来提供信息
元数据Annotation:
包含成员变量的Annotation; 它们可以接受(和提供)更多的元数据;
1.0.4 如何自定义注解
使用@interface关键字, 其定义过程与定义接口非常类似, 需要注意的是:
Annotation的成员变量在Annotation定义中是以无参的方法形式来声明的, 其方法名和返回值类型定义了该成员变量的名字和类型,
而且我们还可以使用default关键字为这个成员变量设定默认值;
二、自定义注解
2.1 案例一(获取类上的注解值)
注解类
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;
/**
* MyAnnotation1注解可以用在类、接口、属性、方法上
* * 注解运行期也保留
* * 不可继承
*/
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation1 {
// @interface 注解修饰符
// 指的是注解中的属性
public String value() default "可以修饰类和属性、方法";
public String desc() default "可以修饰类和属性、方法";
}
使用注解类
package com.zking.ssm.annotation;
/**
* @author javaxy
* @company xxx公司
* @create 2022-11-17 9:18
*/
// value如果标记在属性上面可以省略
@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("测试1");
}
}
注解类2
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;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation2 {
// @interface 注解修饰符
// 指的是注解中的属性
public String value() default "可以修饰类和属性、方法";
public String desc() default "可以修饰类和属性、方法";
}
获取自定义注解中的类容
package com.zking.ssm.annotation.demo;
import com.zking.ssm.annotation.MyAnnotation1;
import com.zking.ssm.annotation.StudentController;
/**
* @author javaxy
* @company xxx公司
* @create 2022-11-17 9:30
*
* 目标:
* 1.获取studentcontroller 类上自定义注解中的类容
* 2.获取studentcontroller 方法上自定义注解中的类容
* 3. 获取studentcontroller 属性上自定义注解中的类容
* 4.获取studentcontroller 参数上自定义注解中的类容
*
* *.Service.Pager(..)
* com.yzp.service.BookService.queryPager(..);
*
*/
public class Demo1 {
public static void main(String[] args) {
MyAnnotation1 annotation = StudentController.class.getAnnotation(MyAnnotation1.class);
System.out.println(annotation.desc());
System.out.println(annotation.value());
}
}
如果现在你现在直接运行代码会报错
如果要运行代码我们需要将这个@Retention(RetentionPolicy.SOURCE)改成
@Retention(RetentionPolicy.RUNTIME)
改完之后的代码
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;
/**
* MyAnnotation1注解可以用在类、接口、属性、方法上
* * 注解运行期也保留
* * 不可继承
*/
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
//RUNTIME 只有运行时才能使用的注解
public @interface MyAnnotation1 {
// @interface 注解修饰符
// 指的是注解中的属性
public String value() default "可以修饰类和属性、方法";
public String desc() default "可以修饰类和属性、方法";
}
运行结果
2.2 案例二 获取注解上的属性值
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;
/**
* @author javaxy
* @company xxx公司
* @create 2022-11-17 9:30
*
* 目标:
* 1.获取studentcontroller 类上自定义注解中的类容
* 2.获取studentcontroller 方法上自定义注解中的类容
* 3. 获取studentcontroller 属性上自定义注解中的类容
* 4.获取studentcontroller 参数上自定义注解中的类容
*
* *.Service.Pager(..)
* com.yzp.service.BookService.queryPager(..);
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
MyAnnotation1 annotation = StudentController.class.getAnnotation(MyAnnotation1.class);
// System.out.println(annotation.desc());
// System.out.println(annotation.value());
// 获取属性上的
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());
// Field[] declaredFields = StudentController.class.getDeclaredFields();
// for (Field f:declaredFields){
// MyAnnotation1 annotation1 = f.getAnnotation(MyAnnotation1.class);
// if(annotation1!=null){
//
// }
// }
//
}
}
2.3 案例三、获取方法上的注解的类容
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;
/**
* @author javaxy
* @company xxx公司
* @create 2022-11-17 9:30
*
* 目标:
* 1.获取studentcontroller 类上自定义注解中的类容
* 2.获取studentcontroller 方法上自定义注解中的类容
* 3. 获取studentcontroller 属性上自定义注解中的类容
* 4.获取studentcontroller 参数上自定义注解中的类容
*
* *.Service.Pager(..)
* com.yzp.service.BookService.queryPager(..);
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
MyAnnotation1 annotation = StudentController.class.getAnnotation(MyAnnotation1.class);
// System.out.println(annotation.desc());
// System.out.println(annotation.value());
// 获取属性上的
// 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());
// Field[] declaredFields = StudentController.class.getDeclaredFields();
// for (Field f:declaredFields){
// MyAnnotation1 annotation1 = f.getAnnotation(MyAnnotation1.class);
// if(annotation1!=null){
//
// }
// }
//
}
}
2.4 案例四 获取参数上的注解
首先要将MyAnnotation2中的注解修改成这个@Retention(RetentionPolicy.RUNTIME),要不然会报跟上面一样的错
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 javaxy
* @company xxx公司
* @create 2022-11-17 9:30
*
* 目标:
* 1.获取studentcontroller 类上自定义注解中的类容
* 2.获取studentcontroller 方法上自定义注解中的类容
* 3. 获取studentcontroller 属性上自定义注解中的类容
* 4.获取studentcontroller 参数上自定义注解中的类容
*
* *.Service.Pager(..)
* com.yzp.service.BookService.queryPager(..);
*
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
MyAnnotation1 annotation = StudentController.class.getAnnotation(MyAnnotation1.class);
// System.out.println(annotation.desc());
// System.out.println(annotation.value());
// 获取属性上的
// 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());
}
// Field[] declaredFields = StudentController.class.getDeclaredFields();
// for (Field f:declaredFields){
// MyAnnotation1 annotation1 = f.getAnnotation(MyAnnotation1.class);
// if(annotation1!=null){
//
// }
// }
//
}
}
三、Aop自定义注解的应用
注解类
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 javaxy
* @company xxx公司
* @create 2022-11-17 10:26
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
String desc();
}
使用注解类
package com.zking.ssm.annotation.aop;
import org.springframework.stereotype.Controller;
/**
* @author javaxy
* @company xxx公司
* @create 2022-11-17 10:28
*/
@Controller
public class DemoController {
@MyLog( desc = "这是一个测试类的方法")
public void test(){
System.out.println("测试方法");
}
}
日志切面类,使用注解的切面的类
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;
/**
* @author javaxy
* @company xxx公司
* @create 2022-11-17 10:31
*/
@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) {
// 目标对象,目标方法,传递的参数
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.shiro;
import com.zking.ssm.annotation.aop.DemoController;
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 javaxy
* @company xxx公司
* @create 2022-10-26 15:29
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class DemoBizTest {
@Autowired
private DemoController dc;
@Test
public void test1(){
dc.test();
}
}
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>org.example</groupId>
<artifactId>ssm2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ssm2 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>
<!--5.其他-->
<junit.version>4.12</junit.version>
<servlet.version>4.0.0</servlet.version>
<lombok.version>1.18.2</lombok.version>
<ehcache.version>2.10.0</ehcache.version>
<slf4j-api.version>1.7.7</slf4j-api.version>
<!--定义redis版本-->
<redis.version>2.9.0</redis.version>
<redis.spring.version>1.7.1.RELEASE</redis.spring.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日志相关依赖-->
<!--核心log4j2jar包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</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>
</dependency>
<!--5.其他-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</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依赖-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<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>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- 做服务端参数校验 JSR303 的jar包依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
<!-- 用来SpringMVC支持json数据转换-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.3</version>
</dependency>
<!-- shiro相关依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
</dependency>
<!-- slf4j核心包 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j-api.version}</version>
<scope>runtime</scope>
</dependency>
<!--用于与slf4j保持桥接 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!--redis整合-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${redis.spring.version}</version>
</dependency>
</dependencies>
<build>
<finalName>ssm2</finalName>
<resources>
<!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
<include>*.xml</include>
</includes>
</resource>
</resources>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<dependencies>
<!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<configuration>
<overwrite>true</overwrite>
</configuration>
</plugin>
<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>
</build>
</project>
测试结果: