当前位置: 首页 > 知识库问答 >
问题:

Spring:ApplicationContextAware有值,但@Autowired没有

暨正真
2023-03-14

几个小时前,我打开了一个问题,它被标记为重复,但是它不是标记问题的重复。

从那以后,我设法完成了一些事情,解决了一些问题,所以我的问题是:

我试图将一个Springbean自动连接到另一个,但是我的问题是@自动连接字段总是空的,这说明它们都是受管理的bean,并且自己可以正确工作。

我发现,通过实现ApplicationContextAware接口,可以在bean中访问ApplicationContext,我做到了这一点。它被调用,并为它提供了正确的上下文。

这样,我可以在上下文中调用getBean(),它返回我首先想要@Autowire的bean,这是一个yaay,但这似乎是一个更大问题的变通方法

你能帮我看看有什么问题吗?我尝试了@Autowiring作为字段、方法和构造函数参数,但都没有成功。这些bean都是单例bean,并用作服务导出器的基础,以便从另一个servlet访问它们。

我想我在这里遗漏了一些重要的配置信息,但是我不明白为什么字段注入不起作用,而同时接口实现起作用。是不是我想@autowire的bean还没有准备好,所以不能注射?

正如你们中的一些人所要求的,这是我的代码。不知道这有什么帮助,但是:

@Service(Persistence.NAME)
public class PersistenceBean implements Persistence, ApplicationContextAware {

ApplicationContext context;

@Override
public User getUser() {
    User user = new User();
    user.setEmail(context.getBean(HelloWorld.class).getText());
    return user;
}

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

和my context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context https://www.springframework.org/context/spring-context.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">


<context:annotation-config />
<context:component-scan base-package="hu.bme.sch.qpa" annotation-config="true"/>

<bean id="sessionFactory"
      class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource"
              ref="dataSource"/>
    <property name="packagesToScan"
              value="hu.bme.sch.qpa.global.entities"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">
                update
            </prop>
            <prop key="hibernate.dialect">
                org.hibernate.dialect.PostgreSQL95Dialect
            </prop>
        </props>
    </property>
</bean>

<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql://localhost:5432/test"/>
    <property name="username" value="qpapp_server_user"/>
    <property name="password" value="root"/>
</bean>

<bean id="txManager"
      class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven/>

<bean id="persistenceExceptionTranslationPostProcessor" class=
        "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

</beans>

最后,我的ApplicationInitializer注释如下:

@ImportResource("/WEB-INF/app-core-servlet.xml")
@SpringBootApplication(scanBasePackages = "hu.bme.sch.qpa")
@EnableWebMvc
@Configuration
@EnableAutoConfiguration
public class CoreStarter extends SpringBootServletInitializer {

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

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);

    }
}

这里是HelloWorldbean,它(顾名思义)是一个非常简单的bean。它与PersistenceBean位于同一个包中:

@Service(HelloWorld.NAME)
public class HelloWorldBean implements HelloWorld {

@Override
public String getText() {
    return "Hello World!!!! I'm remoted";
}
}

提前谢谢。

共有1个答案

曹伟泽
2023-03-14

好的,我知道了。。。男孩做这件事花了一些时间。

因此,事实证明,我所描述的上下文并不包括导致问题的上下文,但我不想用我的整个模块对线程发送垃圾邮件。

缺失的部分是,我正在远程处理这些豆子,只是并且只处理那些在自动连接方面有问题的豆子(当时我不知道)。

我对它们进行远程控制的方式是,我向BeanDefinitionRegistryPostProcessor编写了一个实现。

这样做的问题是,当接口的函数被调用时,我就实例化了远程bean,这意味着:在Spring之前,通常会实例化我想要远程的bean=

我过早地调用getBean()意味着在实例化bean时,AutowiredCapableBeanPostProcessor(或sg.like this)没有在工厂列表中注册,我也无法控制它。

=============================================================TL;博士=================================

解决方案是,在远程导出器bean中,当调用postProcessBeanDefinitionRegistry()函数时,我只需保存注册表,实现实例化WarebeanPostProcessor,并在调用postProcessAfterInstantiation()时进行实际远程处理=

很抱歉占用了你的时间,我真的很感激。

 类似资料:
  • 只是在Spring4.3中从基于xml的配置迁移到基于java的配置。 另外,我尽量不在所有类的所有字段中添加@Autowired注释。这太多了,无法改变。 我现在的问题是:如何通过名称告诉组件扫描到autowire found bean?

  • 我在RestController类中有autowired ApplicationContext,因为我需要为收到的每个请求创建一个原型化的bean。 为了创建bean,我尝试了context.getBean(xx),但context没有列出getBean()方法。有没有一种方法,我可以在我的RestController类中获得原型类的bean。我正在以Spring Boot运行这个应用程序。 更新

  • 也许给出问题的最好方法是在下面显示代码:

  • 我正在尝试用注释配置我的Spring Boot应用程序,并在其中使用@Autowired注释。当我检查是否已加载Bean时,它已加载,但使用@Autowired时,它会显示NoSuchBeanDefinitionException 正如您可以进一步看到的那样,我试图检查我的Bean是否真的被加载了,所以当我运行我的应用程序时,我可以在控制台中看到我的Bean的名称。此外,我尝试将“scanBase

  • 问题内容: 我正在看工作区中的一些旧示例。由于没有 @Autowired, 我看不到自动 装配的方式 。Spring Boot + Facebook默认配置。 它工作完美,但是这些bean如何在没有@Autowired的情况下自动进行自动连线? 它们是作为字段或在构造函数中自动接线的吗? 问题答案: 借助Spring Boot 1.4+,构造函数将自动进行自动接线 https://docs.spr

  • 在将Android-Room版本从2.2.x更新到2.4.x后,我决定使用自动迁移功能来帮助我编写更少的代码。因此,我想弃用所有手动编写的迁移,而改用自动迁移。但是我在使用自动迁移时遇到错误: 即使我以这种方式指定了默认值,但仍然得到相同的错误: 我的代码有什么问题,如何修复此错误? 我有两个版本数据库: 版本 1 然后在版本2中,我在用户表中添加了一个名称为“高度”的列: 版本2 现在我想弃用所