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

求Micronaut中Spring ApplicationContextAware的等效实现(AWS Lambda场景)

在Micronaut中实现Spring的ApplicationContextAware等效功能

背景

在Spring Boot中,我们可以通过ApplicationContextAware接口获取ApplicationContext,从而手动获取容器中的Bean,示例代码如下:

// this is a Spring Boot programme
package com.example.demo

import org.springframework.context.ApplicationContextAware;

public class MyClass implements ApplicationContextAware {

    private MyBean myBean;
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext= applicationContext;
    }

    public void setBean(){
       this.myBean= applicationContext.getBean(MyBean.class);
    }
}

我尝试在Micronaut框架中寻找类似方法,试过ApplicationContextConfigurer、ApplicationContextBuilder等类,但都没生效。

补充:将Micronaut应用部署到AWS Lambda后出现NullPointerException,参考Spring相关解决方案推测底层机制类似,附上项目pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>MicronautExp</artifactId>
  <version>0.1</version>
  <packaging>${packaging}</packaging>

  <parent>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-parent</artifactId>
    <version>3.7.4</version>
  </parent>

  <properties>
    <packaging>jar</packaging>
    <jdk.version>11</jdk.version>
    <release.version>11</release.version>
    <micronaut.version>3.7.4</micronaut.version>
    <micronaut.runtime>netty</micronaut.runtime>
    <micronaut.runtime>lambda</micronaut.runtime>
    <exec.mainClass>com.example.Application</exec.mainClass>
    <exec.mainClass>io.micronaut.function.aws.runtime.MicronautLambdaRuntime</exec.mainClass>
  </properties>

  <repositories>
    <repository>
      <id>central</id>
      <url>https://repo.maven.apache.org/maven2</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-inject</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-validation</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-jackson-databind</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>jakarta.annotation</groupId>
      <artifactId>jakarta.annotation-api</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.test</groupId>
      <artifactId>micronaut-test-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>
    <dependency>
      <groupId>com.googlecode.json-simple</groupId>
      <artifactId>json-simple</artifactId>
      <version>1.1.1</version>
    </dependency>

<!--    micronaut http dependencies. Forgot why they are here, but better not touch it-->
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-http-client</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut</groupId>
      <artifactId>micronaut-http-server-netty</artifactId>
      <scope>compile</scope>
    </dependency>

<!--    graalvm compilers. Forgot why they are here, but better not touch it-->
    <dependency>
      <groupId>org.graalvm.nativeimage</groupId>
      <artifactId>svm</artifactId>
      <version>22.2.0</version>
    </dependency>
    <dependency>
      <groupId>org.graalvm.sdk</groupId>
      <artifactId>graal-sdk</artifactId>
      <version>22.2.0</version>
    </dependency>

<!--    micronaut email dependency-->
    <dependency>
      <groupId>io.micronaut.email</groupId>
      <artifactId>micronaut-email-javamail</artifactId>
    </dependency>
    <dependency>
      <groupId>io.micronaut.email</groupId>
      <artifactId>micronaut-email</artifactId>
      <version>1.5.0</version>
    </dependency>

<!--    AWS Lambda dependencies-->
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-lambda-java-core</artifactId>
      <version>1.2.2</version>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-function-aws-api-proxy</artifactId>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-function-aws-api-proxy-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.micronaut.aws</groupId>
      <artifactId>micronaut-function-aws-custom-runtime</artifactId>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.12.0</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>io.micronaut.build</groupId>
        <artifactId>micronaut-maven-plugin</artifactId>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.10.1</version>
        <configuration>
          <!-- Uncomment to enable incremental compilation -->
          <!-- <useIncrementalCompilation>false</useIncrementalCompilation> -->

          <annotationProcessorPaths combine.children="append">
            <path>
              <groupId>io.micronaut</groupId>
              <artifactId>micronaut-http-validation</artifactId>
              <version>${micronaut.version}</version>
            </path>
          </annotationProcessorPaths>
          <compilerArgs>
            <arg>-Amicronaut.processing.group=com.example</arg>
            <arg>-Amicronaut.processing.module=MicronautExp</arg>
          </compilerArgs>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.4.3</version>
        <configuration>
          <createDependencyReducedPom>false</createDependencyReducedPom>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

解决方案

在Micronaut中,对应Spring的ApplicationContextAware的等效实现有两种常用方式,针对AWS Lambda场景优化如下:

方式1:注入BeanContext

Micronaut的BeanContext是Spring ApplicationContext的直接替代,你可以直接通过构造函数或字段注入的方式获取它,然后手动获取Bean:

package com.example;

import io.micronaut.context.BeanContext;
import jakarta.inject.Singleton;

@Singleton
public class MyClass {
    private final MyBean myBean;

    // 构造函数注入BeanContext并直接获取MyBean
    public MyClass(BeanContext beanContext) {
        this.myBean = beanContext.getBean(MyBean.class);
    }

    // 或者如果需要延迟获取,保留BeanContext引用
    // private final BeanContext beanContext;
    // public MyClass(BeanContext beanContext) {
    //     this.beanContext = beanContext;
    // }
    // public void setBean() {
    //     this.myBean = beanContext.getBean(MyBean.class);
    // }
}

方式2:实现BeanContextAware接口

Micronaut提供了BeanContextAware接口,用法和Spring的ApplicationContextAware几乎一致:

package com.example;

import io.micronaut.context.BeanContext;
import io.micronaut.context.BeanContextAware;
import jakarta.inject.Singleton;

@Singleton
public class MyClass implements BeanContextAware {
    private MyBean myBean;
    private BeanContext beanContext;

    @Override
    public void setBeanContext(BeanContext beanContext) {
        this.beanContext = beanContext;
    }

    public void setBean() {
        this.myBean = beanContext.getBean(MyBean.class);
    }
}

AWS Lambda场景注意事项

  1. 确保类被Micronaut管理:你的MyClass和MyBean必须添加@Singleton(或其他作用域注解),确保被Micronaut的容器扫描并管理。
  2. Lambda入口类的正确配置:如果你的Lambda handler类不是被容器管理的,需要在入口处手动获取BeanContext。例如:
package com.example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import io.micronaut.context.ApplicationContext;

public class LambdaHandler implements RequestHandler<Object, Object> {
    private static final ApplicationContext CONTEXT = ApplicationContext.run();
    private final MyClass myClass = CONTEXT.getBean(MyClass.class);

    @Override
    public Object handleRequest(Object input, Context context) {
        // 使用myClass处理请求
        myClass.setBean();
        return "Success";
    }
}
  1. 移除pom.xml中重复配置:你的pom.xml里micronaut.runtime和exec.mainClass有重复定义,建议保留lambda runtime和MicronautLambdaRuntime主类,避免初始化冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:10:40