Javaは反射を利用して、どうやって指定された注釈を使うクラスを調べますか?
前言
最近空いていますが、自分でspringの注釈と同じような注釈を書いて使って、自分で注釈を書いた種類を見つけたいです。実現方法を紹介します。
声明の下のコードはspringのソースコードを見たことがないので、ほぼすべてネット上で探したブログで、整理しました。
コメントを定義
Controller.java
以下のコードはネットブログからのものです。
注を使ったクラスを探してください。
締め括りをつける
以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考となる学習価値を持っています。質問があれば、メッセージを書いて交流してください。ありがとうございます。
最近空いていますが、自分でspringの注釈と同じような注釈を書いて使って、自分で注釈を書いた種類を見つけたいです。実現方法を紹介します。
声明の下のコードはspringのソースコードを見たことがないので、ほぼすべてネット上で探したブログで、整理しました。
コメントを定義
Controller.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
}
Request Mappingn.java
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
String value();
}
コメントを使う
@Controller
public class IndexController {
@RequestMapping("/")
public void index() {
System.out.println("index method")
}
@RequestMapping("/about")
public void about(String args) {
System.out.println("about method")
}
}
すべてのクラスをスキャンします。以下のコードはネットブログからのものです。
/**
* package Class
*
* @param packageName
* @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;
}
パッケージ名が入ると、自動的に次のクラスをスキャンします。注を使ったクラスを探してください。
// Controller
private List<Class<?>> controllers;
public List<Class<?>> getControllers() {
if (controllers == null) {
controllers = new ArrayList<>();
List<Class<?>> clsList = getAllClass();
if (clsList != null && clsList.size() > 0) {
for (Class<?> cls : clsList) {
if (cls.getAnnotation(Controller.class) != null) {
Map<Class<?>, Object> map = new HashMap<>();
controllers.add(cls);
}
}
}
}
return controllers;
}
Request Mappingを用いて注釈する方法を調べ,注入パラメータを調べた。
for (Class<?> cls : getControllers()) {
Method[] methods = cls.getMethods();
for (Method method : methods) {
RequestMapping annotation = method.getAnnotation(RequestMapping.class);
if (annotation != null) {
String value = annotation.value();// RequestMapping value
if (value.equals("/about")) {// /about, , about(args)
method.invoke(cls.newInstance(), "args"); //
}
}
}
}
このようにして、javaプロジェクトの中で純粋なservletで書いたプロジェクトは自分の注釈マッピングルートを作ることができます。とても便利です。締め括りをつける
以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考となる学習価値を持っています。質問があれば、メッセージを書いて交流してください。ありがとうございます。