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

Spring中@Configurable失效:@Autowired注入Service报NullPointerException求助

Spring @Configurable 无法注入@Autowired Service 问题

我尝试在Spring中使用@Configurable注解,想在手动创建的非Bean类里注入@Autowired修饰的Service,但无论怎么尝试都没法正常工作。之前调研过相关问题,现在完全没头绪,以下是我写的极简代码示例:

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo2</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置扫描类(AspectJConfig)

package com.example.demo2;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;

@Configuration
@ComponentScan
@EnableSpringConfigured
public class AspectJConfig
{
    
}

SpringBoot启动类(Demo2Application)

package com.example.demo2;

import javax.annotation.PostConstruct;

//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class Demo2Application
{
    //@Autowired
    //private HelloWorldService helloWorldService;
    
    public static void main(String[] args)
    {
        SpringApplication.run(Demo2Application.class, args);
    }
    
    @PostConstruct
    public void doSomethingIProbablyShouldNotBeDoing()
    {
        //helloWorldService.sayHello();
        HelloWorldClient client = new HelloWorldClient();
        client.sayHello();
    }
    
}

带@Configurable的客户端类(HelloWorldClient)

package com.example.demo2;

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();
    }
}

Service类(HelloWorldService)

package com.example.demo2;

import org.springframework.stereotype.Service;

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

之前我在相关问题中得到过有效解决方案,但现在在当前环境下无法正常运行。


解决方案

1. 补全AspectJ核心依赖

@Configurable依赖AspectJ织入实现对象注入,你的pom.xml缺少关键依赖,需添加:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

2. 启用AspectJ织入

@Configurable必须通过AspectJ织入才能生效,二选一即可:

方式一:编译时织入(推荐)

在pom.xml的build/plugins中添加AspectJ编译插件,确保编译阶段完成织入:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.14.0</version>
    <configuration>
        <complianceLevel>17</complianceLevel>
        <source>17</source>
        <target>17</target>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
            </aspectLibrary>
        </aspectLibraries>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

方式二:加载时织入

如果不想修改编译流程,可启用加载时织入:

  • 在src/main/resources下创建META-INF/aop.xml:
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver>
        <include within="com.example.demo2..*"/>
    </weaver>
    <aspects>
        <aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"/>
    </aspects>
</aspectj>
  • 启动时添加JVM参数:-javaagent:/path/to/aspectjweaver.jar(IDE中可在VM Options里配置)

3. 明确@Configurable注入规则

给@Configurable添加属性,指定注入方式:

@Configurable(autowire = Autowire.BY_TYPE)
public class HelloWorldClient {
    // ...
}

4. 调整对象创建时机

@PostConstruct执行时Spring上下文可能未完全初始化,改为在上下文就绪后创建对象:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class Demo2Application implements ApplicationListener<ContextRefreshedEvent> {

    public static void main(String[] args) {
        SpringApplication.run(Demo2Application.class, args);
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        HelloWorldClient client = new HelloWorldClient();
        client.sayHello();
    }
}

5. 简化Spring配置

将@EnableSpringConfigured直接加到启动类上,避免配置类被遗漏扫描:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableSpringConfigured
public class Demo2Application {
    // ...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:30:44