Spring @configurable NullPointerException

Spring @configurable NullPointerException

我尝试在我的项目中使用@configurable 以在spring 上下文或类似内容之外的对象中使用@autowired 服务,但未能成功。该服务始终为空。

(我比较了 4 个不同的教程,但没有任何效果)

所以,绝望的我尝试直接下载工作示例来比较它们,但它们并没有那么好用。 (但我不得不稍微修改一下,见“注释”)

这是我尝试下载的两个示例,但也给了我一个 nullPointerException:
https://github.com/kenyattaclark/Spring-Configurable-Example
https://www.baeldung.com/spring-inject-bean-into-unmanaged-objects(link在页尾)

那么,这些例子对你有用吗?我是否错过了一些非常重要的事情?

备注:
我正在使用 java 的 correto 版本(但我想问题不太可能来自这里)

我必须对这两个示例进行一些更改才能使它们正常工作,所以也许这就是原因:
对于第一个,我在 pom 中添加了一个 <pluginManagement>,因为如果我不这样做,eclipse 会给我一个错误“生命周期配置未涵盖的插件执行”,如果我尝试编译我有错误:“错误无法确定缺失类型的超类 java.lang.Object 批量构建时BuildConfig[null] #Files=3 AopXmls=#0 [Xlint:cantFindType]
对于第二个,我没有使用 <pluginManagement>。但我没有下载父文件夹,所以我在 pom 中更改了它,并将 java 版本强制为 11,或者 maven 将其重置为 1.5 并且不得不将 junit 测试更新为 junit5.

所以我有空间把这一切搞砸,但我厌倦了在互联网上到处寻找,甚至找不到一个可用的例子。
所以,如果有人知道哪里出了问题或如何制作一个 @configurable 示例,请告诉我。

我看了第一个例子。它使用非常旧版本的 Spring、AspectJ 和 AspectJ Maven 插件。我升级了 POM 以使用

  • Spring 5.3.16,
  • AspectJ 1.9.9(最多支持 Java18)
  • AspectJ.dev AspectJ Maven 插件 1.13.1(比 Mojohaus 更好更新,还支持 Java 18,将来只需升级 aspectjtools插件依赖,无需升级插件)。

请在您的构建系统上使用 JDK 11+。更新的 AspectJ 编译器版本需要它。不过,您仍然可以编译为 Java 8 字节代码。 (但你为什么要这么做?)

这是 Maven POM。我还添加了一个单独的依赖项管理部分,以便全局管理依赖项版本和排除项。然后我使用 mvn dependency:analyzemvn dependency:tree 来清理使用过的未声明和 delcared 未使用的依赖项。如果您的项目需要另一组依赖项,您当然需要根据需要进行调整。我只是为这个小示例程序中使用的内容配置了它。这样做时,我还清除了一些未使用的 XML name-space 和模式声明。如果您的程序中需要它们,只需重新添加它们即可。

<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.brightdome</groupId>
  <artifactId>spring-configurable-sample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Spring Configurable Sample</name>
  <description>
    Sample project to show how to work with Spring's @Configurable capability
    to inject dependencies into classes not instantiated by Spring.
  </description>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <aspectj.version>1.9.9</aspectj.version>
    <spring.version>5.3.16</spring.version>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
      </plugin>
      <plugin>
        <groupId>dev.aspectj</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.13.1</version>
        <dependencies>
          <!-- Override older AspectJ compiler in plugin, use latest one -->
          <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
          </dependency>
        </dependencies>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
          <aspectLibraries>
            <aspectLibrary>
              <groupId>org.springframework</groupId>
              <artifactId>spring-aspects</artifactId>
            </aspectLibrary>
          </aspectLibraries>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${spring.version}</version>
        <exclusions>
          <!-- Only needed for load-time weaving, not compile-time -->
          <exclusion>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
      </dependency>
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>${aspectj.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
    </dependency>
    <!-- Needed by spring-aspects -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
    </dependency>
    <!-- Needed by compile-time aspects during runtime -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
    </dependency>
  </dependencies>

</project>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  "
>
  <context:spring-configured/>
  <context:component-scan base-package="com.brightdome"/>
  <context:annotation-config/>
</beans>
package com.brightdome.sample.spring;

import org.springframework.stereotype.Service;

@Service
public class HelloWorldService {
  public void sayHello() {
    System.out.println("Hello world!");
  }
}
package com.brightdome.sample.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

@Configurable
public class HelloWorldClient {
  @Autowired
  private HelloWorldService service;

  public void sayHello() {
    // Used injected instance of service
    service.sayHello();
  }
}
package com.brightdome.sample.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloWorld {
  public static void main(String[] args) {
    // Initialize Spring Context
    new ClassPathXmlApplicationContext("/META-INF/applicationContext.xml");

    // Instantiate class by new'ing it up. i.e., Do not obtain from Spring context
    HelloWorldClient client = new HelloWorldClient();
    client.sayHello();
  }
}

这在我的 IDE (IntelliJ IDEA) 和 Maven 中编译和运行都很好。在控制台上,它应该简单地打印 "Hello world!" 然后退出。