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

AEM环境中@Inject注入服务触发空指针,@Reference可成功注入

解决AEM中@SlingServlet类用@Inject注入服务空指针的问题

咱先拆解下你遇到的问题:在用org.apache.felix.maven-scr-plugin构建AEM OSGi组件时,给@SlingServlet修饰的MyServlet用javax.inject.Inject注入MyConfigurationService会报空指针,但换成org.apache.felix.scr.annotations.Reference就正常,核心原因是插件和注解体系不兼容。

为啥@Inject会失效?

maven-scr-plugin是基于旧版的Felix SCR注解体系工作的——它只会识别org.apache.felix.scr.annotations包下的注解(比如@Reference、@Component),根本不认识javax.inject.Inject这类属于OSGi Declarative Services(DS)的注解。所以插件在生成OSGi组件元数据时,完全不会处理@Inject标记的字段,导致你的myConfigurationService一直是null,调用方法自然就抛空指针了。

两种可行的解决办法

办法1:继续使用SCR注解体系(快速适配)

如果你暂时不想调整构建插件,直接沿用@Reference注解就没问题,这也是maven-scr-plugin原生支持的方式:

import org.apache.felix.scr.annotations.Reference;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServlet;

@SlingServlet(paths = "/content/my/servlet/path")
public class MyServlet extends SlingSafeMethodsServlet {

    @Reference
    private MyConfigurationService myConfigurationService;

    // 后续调用myConfigurationService的方法就正常了
}

办法2:迁移到OSGi DS注解体系(推荐长期方案)

现在AEM官方更推荐使用OSGi Declarative Services(DS)的注解体系,你需要把构建插件换成支持DS的maven-bundle-plugin,同时调整注解:

  1. 替换Maven插件:在pom.xml中移除maven-scr-plugin,添加并配置maven-bundle-plugin,确保它能处理DS注解:
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>5.1.9</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
            <Bundle-Version>${project.version}</Bundle-Version>
            <!-- 启用DS注解处理 -->
            <Service-Component>OSGI-INF/*.xml</Service-Component>
            <Export-Package>com.yourpackage.*</Export-Package>
        </instructions>
    </configuration>
</plugin>
  1. 调整Servlet类的注解,使用DS的@Component和@Inject:
import javax.inject.Inject;
import org.osgi.service.component.annotations.Component;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletResourceTypes;

// 用DS的@Component标记为OSGi组件,配合SlingServlet的注解
@Component(service = {javax.servlet.Servlet.class})
@SlingServletResourceTypes(
    resourceTypes = "your-project/components/page",
    methods = "GET"
)
public class MyServlet extends SlingSafeMethodsServlet {

    @Inject
    private MyConfigurationService myConfigurationService;

    // 现在调用myConfigurationService就不会空指针了
}

注意:如果你的Servlet是通过路径绑定的,也可以用@SlingServlet(paths = "/content/my/path"),但要确保@Component的service属性包含javax.servlet.Servlet.class,这样OSGi才能识别它是一个Servlet服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:26:15