【问题标题】:Error with private field using @Autowired使用 @Autowired 的私有字段出错
【发布时间】:2021-02-07 23:10:55
【问题描述】:

我在使用 Spring 更改变量的可见性时出错。

我有这段代码(可以正常工作)

@Component
public class TennisCoach implements Coach {

    @Autowired
    public FortuneService fortuneService;

    @Override
    public String getDailyWorkout() {
        return "Do tennis stuff!";
    }

    @Override
    public String getFortune() {
        return fortuneService.getFortune();
    }

}

FortunateService 是一个接口,我有一个实现它的类HappyFortunateService,我还用@Component 对其进行了注释)

用这个主要方法

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Coach annotatedCoach = context.getBean("tennisCoach", Coach.class);

    System.out.println(annotatedCoach.getDailyWorkout());
    System.out.println(annotatedCoach.getFortune());

    context.close();

}

当我打开TennisCoachfortunateService 变量对private 的可见性时,我收到此错误:

org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tennisCoach': Injection of autowired dependencies failed; nested exception is java.lang.reflect.InaccessibleObjectException: Unable to make field private me.davichete.springproject.FortuneService me.davichete.springproject.TennisCoach.fortuneService accessible: module spring_project does not "opens me.davichete.springproject" to module spring.core
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tennisCoach': Injection of autowired dependencies failed; nested exception is java.lang.reflect.InaccessibleObjectException: Unable to make field private me.davichete.springproject.FortuneService me.davichete.springproject.TennisCoach.fortuneService accessible: module spring_project does not "opens me.davichete.springproject" to module spring.core
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:405)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
    at spring.context@5.2.9.RELEASE/org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
    at spring.context@5.2.9.RELEASE/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
    at spring.context@5.2.9.RELEASE/org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
    at spring.context@5.2.9.RELEASE/org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
    at spring_project/me.davichete.springproject.HelloSpringApp.main(HelloSpringApp.java:8)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private me.davichete.springproject.FortuneService me.davichete.springproject.TennisCoach.fortuneService accessible: module spring_project does not "opens me.davichete.springproject" to module spring.core
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:361)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:301)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:177)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:171)
    at spring.core@5.2.9.RELEASE/org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:782)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:667)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
    at spring.beans@5.2.9.RELEASE/org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
    ... 13 more

有人知道为什么吗? 春季版:5.2.9 Java SE15

编辑:我的项目设置为将 Spring JAR 文件添加到 ModulePath,我没有使用 Maven。

我的 module-info.java 看起来像这样:

module spring_project {
    requires spring.context;
    requires java.logging;
    requires spring.beans;

    exports me.davichete.springproject;
}

编辑:我测试它删除module-info.java,现在它似乎工作,可能与@Menelaos 的答案有关

【问题讨论】:

    标签: java spring autowired


    【解决方案1】:

    尝试添加一个构造函数并使您的字段成为最终字段

    如果您使用的是Lambok,您可以执行以下操作:

    1. 在您的类上设置@RequiredArgsConstructor - 这将为所有最终变量生成一个带有参数的构造函数。
    2. 将您的字段更改为 final,并删除 @Autowired。

    Spring 将负责为 final 字段注入值。

    如果不使用lambok,则需要手动添加构造函数。

    见构造函数注入示例@https://stackoverflow.com/a/55473346/1688441

    Java 9 模块

    还请查看以下内容:How to solve InaccessibleObjectException ("Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}") on Java 9?

    您的错误是由于 Java 9 的限制和更改造成的。

    【讨论】:

    • 我的项目已经导出了,但是还是不行:(
    • 是的,我同意,看起来他创建的模块不会导出包含该类的包。
    • 其实建议去掉@Autowired,改用构造函数注入。见:stackoverflow.com/questions/40620000/…
    • @Davichete 完成。删除了模块代码。
    • @Menelaos 谢谢,顺便说一句,这句话非常有帮助,我建议再次添加:D:“您的错误是由于 Java 9 的限制和更改造成的。”
    猜你喜欢
    • 1970-01-01
    • 2015-07-26
    • 2015-04-25
    • 2013-05-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多