Java 使用注解代替配置文件
有这样一个需求,需要在定义main方法的类的外边使用一个注解@Proannotation,我们通过向这个注解传递两个参数来实现让程序执行特定类的特定方法。传递的形式如下;
@Proannotation(className="com.duanlianda.annotationPackage.Student",methodName="printStudentNumber")
目标类(Student.class extends from Person.class)
这里的继承关系似乎有点多余,只看Student类就好
Main方法的类
package com.duanlianda.annotationPackage;
import java.lang.reflect.Method;
/**
* @program: AnnotationTestProject
* @description: ThisIsTo run main method of this demo programe
* @author: Mr.Duan
* @create: 2021-10-08 11:44
**/
@Proannotation(className="com.duanlianda.annotationPackage.Student",methodName="printStudentNumber")
public class MainDemo {
public static void main(String[] args) throws Exception{
// 1:注解的解析
// 获取该类(或者该注解定义位置的,可以是类或者方法的)的字节码文件对象
Class<MainDemo> reflectMainDemoObj = MainDemo.class;
// 2:通过本类的对象,进一步获取本类中使用到的注解的字节码文件对象
Proannotation proannotationObj = reflectMainDemoObj.getAnnotation(Proannotation.class);
// 3:分别以字符串的形式获取注解中储存的两个变量
String className = proannotationObj.className();
String methodName = proannotationObj.methodName();
System.out.println(className+"-------"+methodName);
//加载类到内存中
Class cls = Class.forName(className);
// 使用已经加载到内存中的类创建对象
Student Demoobj = (Student)cls.getDeclaredConstructor(int.class,String.class,String.class).newInstance(25,"duan","852273");
System.out.println(Demoobj);
//获取方法对象
Method targetMethod = cls.getDeclaredMethod(methodName);
// 执行方法
targetMethod.invoke(Demoobj);
}
}
类定义
Person.class
package com.duanlianda.annotationPackage;
/**
* @program: AnnotationTestProject
* @description: This is a Class for demo
* @author: Mr.Duan
* @create: 2021-10-07 12:12
**/
public class Person {
public int age = 0;
public String name = "NonamePerson";
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public void showName() {
System.out.println(name);
}
public void showAge() {
System.out.println(age);
}
}
Student.class
package com.duanlianda.annotationPackage;
/**
* @program: AnnotationTestProject
* @description: This student class is extented from Person class
* @author: Mr.Duan
* @create: 2021-10-08 11:48
**/
public class Student extends Person {
private String studentNumber;
public Student(int age, String name, String studentNumber) {
super(age, name);
this.studentNumber = studentNumber;
}
public void printStudentNumber() {
System.out.println("Student Numebr is :" + this.studentNumber);
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", studentNumber='" + studentNumber + '\'' +
'}';
}
}
注解的定义
package com.duanlianda.annotationPackage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
//使用Target锁定这个注解作用在类上
@Retention(RetentionPolicy.RUNTIME)
//将这个注解定义为在RUNTIME保留
public @interface Proannotation {
//这里是实现了两个与变量同名的方法,返回这两个参数的值
String className();
String methodName();
}
执行结果
/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=59967:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/lianda_duan/Desktop/AnnotationTestProject/out/production/AnnotationTestProject com.duanlianda.annotationPackage.MainDemo
com.duanlianda.annotationPackage.Student-------printStudentNumber
Student{age=25, name='duan', studentNumber='852273'}
Student Numebr is :852273
Process finished with exit code 0