簡體   English   中英

在運行時閱讀裝飾有特定注釋的所有類

[英]Read all classes decorated with a particular annotation at runtime

我需要在運行時閱讀所有裝飾有特定注釋(例如@HttpSecurity)的類(接口)。 掃描后,我希望閱讀和解析裝飾有注釋的類的字段(枚舉字段)。 例如。

@HttpSecurity
public interface MyHttpSecurityConfig {

public enum secure {
    @Path(pathGroup = "/*", pathName = "")
    @Authc
    @Form(errorPage = "/error.html", loginPage = "/login.html", restoreOriginalRequest = "")
    @Authz
    @AllowedRoles(roles = { "roleA", "roleB" })
    @AllowedGroups(groups = { "groupA" })
    @AllowedRealms(realms = { "realmA" })
    @Expressions(expressions = { "#{identity.isLoggedIn()}" })
    Admin
  }
}

可能存在一個或多個用@HttpSecurity裝飾的類/接口。 我的第一個要求是獲取所有此類 ,第二個要求是通過讀取注釋及其在枚舉字段上修飾的值來構建HttpSecurityBuilder。 第二個要求很好,可以使用反射消除。 但是, 我的問題是第一個要求 我想用JavaSE核心實現第一個要求,即不使用任何外部依賴項,例如google Reflections。 如有必要,可以假定我們具有要在其中掃描類的程序包名稱。 這是我做過什么用CDI

您可以創建一個CDI擴展,以觀察來自CDI注釋的掃描並創建您的自定義,如下例所示:

1)您需要使用@HttpSecurity創建一個Qualifier

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface HttpSecurity {}

2)您需要通過實現接口javax.enterprise.inject.spi.Extension創建擴展:

    package net.mperon.cdi.extension;

    public class MyExtension implements Extension {

    private static final Logger log = LoggerFactory.getLogger(MyExtension.class);

    public <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> pat) {
        AnnotatedType<T> at = pat.getAnnotatedType();

        //if dont have you anotation, just continue
        if(!at.isAnnotationPresent(HttpSecurity.class)) {
            return;
        }

        //here you can read all annotation from object and do whatever you want:
        log.info("class: {}", at.getJavaClass());
        log.info("constructors: {}", at.getConstructors());
        log.info("fields: {}", at.getFields());
        log.info("methods: {}", at.getMethods());

        //and so more...

    }

}

3)您可以在此處查看所有方法和屬性

4)最后,您需要在META-INF / services下創建一個名為javax.enterprise.inject.spi.Extension的服務文件。

5)在此文本文件中,您需要輸入擴展名全類名,例如:

net.mperon.cdi.extension.MyExtension

不幸的是,Java沒有提供一種簡便的方法來在“本地” JRE中列出類。 我最喜歡的解決方案是Google Reflections庫,但是如果您不想使用它,則可以使用其他方法。 一種方法是找到一個或多個罐子,然后掃描它們以查找類文件上的注釋。 這可以通過以下方式實現:

// Jars are really just zip files with a different name
ZipInputStream zip = new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));

for(ZipEntry entry=zip.getNextEntry(); entry!=null; entry=zip.getNextEntry()) {
    String name = entry.getName();

    // We only want class files
    if(name.endsWith(".class") && !entry.isDirectory()) {

        // Remove the .class extension
        name = name.substring(0, name.length() - 6);

        // Replace the slashes in the path with '.'
        name.replaceAll("/",".");

        // Get the class object so we can use reflection on it
        Class<?> cls = Class.forName(name);
    }        
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM