You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WildFly JavaEE部署中查找自定义注解类的最优方案及资源保护

在WildFly中查找带自定义注解的类并实现资源保护的最优方案

在WildFly环境里要实现部署时扫描自定义注解类并缓存,同时做好资源保护,我给你梳理下最优方案和具体步骤:

一、扫描自定义注解类的最优方式:CDI扩展(推荐)

CDI是Jakarta EE的标准特性,WildFly原生支持,这种方式跨服务器兼容,实现起来简洁,不需要依赖WildFly特定API,是首选方案。

步骤1:实现CDI扩展类

创建一个实现javax.enterprise.inject.spi.Extension的类,通过观察ProcessAnnotatedType事件来捕获所有带自定义注解的类:

import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class CustomAnnotationScanner implements Extension {
    // 用线程安全的集合存储扫描到的类,避免并发问题
    private final Set<Class<?>> annotatedClasses = Collections.synchronizedSet(new HashSet<>());

    // 监听ProcessAnnotatedType事件,筛选带目标注解的类
    <T> void onProcessAnnotatedType(@Observes ProcessAnnotatedType<T> event) {
        if (event.getAnnotatedType().isAnnotationPresent(MyCustomAnnotation.class)) {
            annotatedClasses.add(event.getAnnotatedType().getJavaClass());
        }
    }

    // 对外提供只读的缓存集合,防止外部修改
    public Set<Class<?>> getAnnotatedClasses() {
        return Collections.unmodifiableSet(annotatedClasses);
    }
}

步骤2:注册CDI扩展

在项目的META-INF/services目录下创建文件javax.enterprise.inject.spi.Extension,内容为你的扩展类全限定名,比如:

com.example.annotation.CustomAnnotationScanner

这样WildFly在部署时会自动识别并加载这个扩展。

步骤3:封装缓存供业务访问

把扫描到的类缓存封装成一个CDI Bean,方便业务代码注入使用:

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.Set;

@ApplicationScoped
public class AnnotatedClassCache {
    private final CustomAnnotationScanner scanner;

    // 构造注入CDI扩展类
    @Inject
    public AnnotatedClassCache(CustomAnnotationScanner scanner) {
        this.scanner = scanner;
    }

    // 对外提供缓存的类集合
    public Set<Class<?>> getCachedAnnotatedClasses() {
        return scanner.getAnnotatedClasses();
    }
}

二、备选方案:WildFly特定部署处理器

如果需要更底层的部署阶段控制(比如在类加载前处理),可以使用WildFly的DeploymentUnitProcessor,但这种方式依赖WildFly API,跨服务器兼容性差:

步骤1:实现部署处理器

import org.jboss.as.server.deployment.Attachments;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.AnnotationInstance;
import java.util.Collection;

public class WildFlyAnnotationScannerProcessor implements DeploymentUnitProcessor {
    @Override
    public void deploy(DeploymentPhaseContext phaseContext) {
        DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
        // 获取WildFly的类索引(由Jandex生成,高效扫描类注解)
        IndexView index = deploymentUnit.getAttachment(Attachments.INDEX);
        if (index != null) {
            // 查找所有带自定义注解的类
            Collection<AnnotationInstance> annotations = index.getAnnotations(MyCustomAnnotation.class.getName());
            for (AnnotationInstance annotation : annotations) {
                String className = annotation.target().asClass().name().toString();
                try {
                    Class<?> clazz = deploymentUnit.getClassLoader().loadClass(className);
                    // 将clazz存入线程安全的缓存集合
                } catch (ClassNotFoundException e) {
                    // 处理类加载异常
                }
            }
        }
    }

    @Override
    public void undeploy(DeploymentUnit deploymentUnit) {
        // 部署卸载时清理缓存,避免内存泄漏
    }
}

步骤2:注册部署处理器

需要将处理器打包成WildFly模块,并在jboss-deployment-structure.xml中配置依赖,这个过程相对繁琐,适合有WildFly定制需求的场景。

三、资源保护方案

1. 缓存访问控制

通过CDI的安全注解限制缓存的访问权限,比如使用@RolesAllowed:

import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.Set;

@ApplicationScoped
@RolesAllowed("ANNOTATION_ADMIN") // 只有拥有ANNOTATION_ADMIN角色的用户能访问
public class AnnotatedClassCache {
    // ... 原有代码
}

同时需要在WildFly中配置相应的安全域和角色映射,确保只有授权用户能调用缓存方法。

2. 线程安全保护

缓存集合必须使用线程安全的实现,比如Collections.synchronizedSet、CopyOnWriteArraySet或ConcurrentHashMap(如果需要键值对存储),避免多线程访问时出现并发修改异常。

3. 类加载安全

如果使用WildFly部署处理器,要确保处理器所在的模块拥有足够的类加载权限,在module.xml中添加必要的依赖:

<module xmlns="urn:jboss:module:1.3" name="com.example.annotation.processor">
    <resources>
        <resource-root path="annotation-processor.jar"/>
    </resources>
    <dependencies>
        <module name="org.jboss.as.server"/>
        <module name="org.jboss.jandex"/>
        <module name="javax.enterprise.api"/>
        <module name="javax.annotation.api"/>
    </dependencies>
</module>

4. 缓存只读保护

对外暴露缓存时,返回不可修改的集合(比如Collections.unmodifiableSet),防止外部代码意外修改缓存内容,保证数据一致性。

内容的提问来源于stack exchange,提问作者Net_Hans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:48:53