关于注解扫描获取类注解信息及对象实例

  • calss获取接口的信息,class的工具类实现扫描 对应包下的接口的实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package org.physical.examination.framework;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.physical.examination.framework.expression.ICalculate;

/**
* 类相关的工具类
*
* @author <a href="mailto:ohergal@gmail.com">ohergal</a>
*
*/
public class ClassUtil {

public static void main(String[] args) throws Exception {
List<Class> classes = ClassUtil.getAllClassByInterface("org.physical.examination.framework.expression",
ICalculate.class);
for (Class clas : classes) {
System.out.println(clas.getName());
}
}

/**
* 取得某个接口下所有实现这个接口的类
* */
public static List<Class> getAllClassByInterface(String packageName, Class base) {
List<Class> returnClassList = null;
if (base.isInterface()) {
// 获取当前的包名
// 获取当前包下以及子包下所以的类
List<Class<?>> allClass = getClasses(packageName);
if (allClass != null) {
returnClassList = new ArrayList<Class>();
for (Class classes : allClass) {
// 判断是否是同一个接口
if (base.isAssignableFrom(classes)) {
// 本身不加入进去
if (!base.equals(classes)) {
returnClassList.add(classes);
}
}
}
}
}

return returnClassList;
}

/*
* 取得某一类所在包的所有类名 不含迭代
*/
public static String[] getPackageAllClassName(String classLocation, String packageName) {
// 将packageName分解
String[] packagePathSplit = packageName.split("[.]");
String realClassLocation = classLocation;
int packageLength = packagePathSplit.length;
for (int i = 0; i < packageLength; i++) {
realClassLocation = realClassLocation + File.separator + packagePathSplit[i];
}
File packeageDir = new File(realClassLocation);
if (packeageDir.isDirectory()) {
String[] allClassName = packeageDir.list();
return allClassName;
}
return null;
}

/**
* 从包package中获取所有的Class
* @param pack
* @return
*/
public static List<Class<?>> getClasses(String packageName) {

// 第一个class类的集合
List<Class<?>> classes = new ArrayList<Class<?>>();
// 是否循环迭代
boolean recursive = true;
// 获取包的名字 并进行替换
String packageDirName = packageName.replace('.', '/');
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
Enumeration<URL> dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
// 循环迭代下去
while (dirs.hasMoreElements()) {
// 获取下一个元素
URL url = dirs.nextElement();
// 得到协议的名称
String protocol = url.getProtocol();
// 如果是以文件的形式保存在服务器上
if ("file".equals(protocol)) {
// 获取包的物理路径
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
// 以文件的方式扫描整个包下的文件 并添加到集合中
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
} else if ("jar".equals(protocol)) {
// 如果是jar包文件
// 定义一个JarFile
JarFile jar;
try {
// 获取jar
jar = ((JarURLConnection) url.openConnection()).getJarFile();
// 从此jar包 得到一个枚举类
Enumeration<JarEntry> entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/开头的
if (name.charAt(0) == '/') {
// 获取后面的字符串
name = name.substring(1);
}
// 如果前半部分和定义的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"结尾 是一个包
if (idx != -1) {
// 获取包名 把"/"替换成"."
packageName = name.substring(0, idx).replace('/', '.');
}
// 如果可以迭代下去 并且是一个包
if ((idx != -1) || recursive) {
// 如果是一个.class文件 而且不是目录
if (name.endsWith(".class") && !entry.isDirectory()) {
// 去掉后面的".class" 获取真正的类名
String className = name.substring(packageName.length() + 1, name.length() - 6);
try {
// 添加到classes
classes.add(Class.forName(packageName + '.' + className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}

return classes;
}

/**
* 以文件的形式来获取包下的所有Class
* @param packageName
* @param packagePath
* @param recursive
* @param classes
*/
public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive,
List<Class<?>> classes) {
// 获取此包的目录 建立一个File
File dir = new File(packagePath);
// 如果不存在或者 也不是目录就直接返回
if (!dir.exists() || !dir.isDirectory()) {
return;
}
// 如果存在 就获取包下的所有文件 包括目录
File[] dirfiles = dir.listFiles(new FileFilter() {
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
public boolean accept(File file) {
return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
}
});
// 循环所有文件
for (File file : dirfiles) {
// 如果是目录 则继续扫描
if (file.isDirectory()) {
findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive,
classes);
} else {
// 如果是java类文件 去掉后面的.class 只留下类名
String className = file.getName().substring(0, file.getName().length() - 6);
try {
// 添加到集合中去
classes.add(Class.forName(packageName + '.' + className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
}
  • 通过注解获取我对象实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void Scan() {
String pageNameString = "org.physical.examination.framework.expression";
List<Class> classes = ClassUtil.getAllClassByInterface(pageNameString, ICalculate.class);
for (Class classType : classes) {
Annotation tempAnnotation = classType.getAnnotation(CalculateAnnotation.class);
if (tempAnnotation != null && tempAnnotation instanceof CalculateAnnotation) {
CalculateAnnotation tempMsgCode = (CalculateAnnotation) tempAnnotation;
try {
ExcuteMaps.put(tempMsgCode.groupName() + "_" + tempMsgCode.innerID(), classType);
} catch (Exception e) {
Log4jUtil.error("解析注解错误", e);
}
}
}
  • 设计注解的接口的内部的key值
1
2
3
4
5
6
7
8
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface CalculateAnnotation {

String groupName() default "";
String desc() default "";
String innerID() default "";
}
  • 设计一个接口,其他的类必须实现这个接口,这样通过扫描这个接口就可以扫描到全部的实现类了
1
2
3
public interface ICalculate {
String Calculate(String[] args);
}
  • 实现类一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@CalculateAnnotation(groupName="BMI",innerID="1",desc="通用")
public class BMICalculate implements ICalculate {

/**
* <p>Title: Calculate</p>
* <p>Description: </p>
* @param args
* @return
* @see org.physical.examination.framework.expression.ICalculate#Calculate(java.lang.String[])
*/
@Override
public String Calculate(String[] args) {
// TODO Auto-generated method stub
return null;
}
}
  • 实现类二
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@CalculateAnnotation(groupName="BMI",innerID="2",desc="another")
public class BMIAnother implements ICalculate{

/**
* <p>Title: Calculate</p>
* <p>Description: </p>
* @param args
* @return
* @see org.physical.examination.framework.expression.ICalculate#Calculate(java.lang.String[])
*/
@Override
public String Calculate(String[] args) {
// TODO Auto-generated method stub
return null;
}
}
  • 就是通过外部application.properties外部配置来获取那个具体的实现类来实现具体的业务逻辑,就是这样
  • 通过反射来获取对象,执行相关的实现类的方法。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    public String Execut(String gropStrings, String innerId, String[] args) {
    CalculateMange.Scan();
    String spellNameString = gropStrings + "_" + innerId;
    Class<ICalculate> clazz = ExcuteMaps.get(spellNameString);
    String calculate = "";
    ICalculate newInstance = null;
    try {
    newInstance = clazz.newInstance();
    calculate = newInstance.Calculate(args);
    } catch (InstantiationException | IllegalAccessException e) {
    e.printStackTrace();
    }
    return calculate;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值