Java Spring将数据源bean注入或自动连接到类

Java Spring将数据源bean注入或自动连接到类,java,spring,jdbc,autowired,Java,Spring,Jdbc,Autowired,这可能是一个非常新手的问题,但我已经搜索过了,要么我的理解有很大的差距,要么我做了一些我无法理解的错误的事情 在我的上下文文件中,这里有一个摘录 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${datasource.driverClassName}" /&

这可能是一个非常新手的问题,但我已经搜索过了,要么我的理解有很大的差距,要么我做了一些我无法理解的错误的事情

在我的上下文文件中,这里有一个摘录

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${datasource.driverClassName}" />
    <property name="url" value="${datasource.url}" />
    <property name="username" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
</bean>

<bean id="myBeanOne" class="a.b.c.myBeanOne">
         <property name="dataSource" ref="dataSource" />
</bean>
当我尝试在调用setDataSource的行上执行此操作时,会出现以下错误:

ERROR org.springframework.integration.handler.LoggingHandler 
    org.springframework.integration.MessageHandlingException: 
       java.lang.NullPointerException
在线:
this.jdbcTemplate.update(sql)

我已经尝试了十种不同的配置来让它工作,但我似乎无法做到这一点。非常感谢您的帮助,谢谢

编辑:根据Luiggi的评论:

//in yet another classes run method
myBeanOne bOne = SomeOtherClass.create();   //just returns new myBeanOne
bOne.myMethod();
任何其他类或此类在上下文中都不被归类为bean,也不存在于上下文中

我知道这是一个非常基本的问题,但我正在努力解决它

谢谢你的耐心

NullPointerException
行:this.jdbcTemplate.update(sql)

如果NPE实际上在那一行,那么
this.jdbcTemplate
显然是
null
。如果这是真的,则:

  • Spring中没有调用
    setDataSource(…)
    方法,可能是因为
    @Autowired
    不正确。添加
    System.out.println(…)
    或在
    setDataSource
    中放置调试断点以查看是否正在调用它是很容易的

  • 如果正在调用它,那么可能有多个
    a.b.c.myBeanOne
    ?您确定要从Spring上下文中的另一个类调用实例吗?在
    setDataSource
    中放置一个断点,并注意
    this
    对象引用id。然后在
    this.jdbcTemplate.update(…)
    行上放置一个断点,并确保
    this
    引用id相同

NullPointerException
行:this.jdbcTemplate.update(sql)

如果NPE实际上在那一行,那么
this.jdbcTemplate
显然是
null
。如果这是真的,则:

  • Spring中没有调用
    setDataSource(…)
    方法,可能是因为
    @Autowired
    不正确。添加
    System.out.println(…)
    或在
    setDataSource
    中放置调试断点以查看是否正在调用它是很容易的

  • 如果正在调用它,那么可能有多个
    a.b.c.myBeanOne
    ?您确定要从Spring上下文中的另一个类调用实例吗?在
    setDataSource
    中放置一个断点,并注意
    this
    对象引用id。然后在
    this.jdbcTemplate.update(…)
    行上放置一个断点,并确保
    this
    引用id相同


如评论中所述,问题在于您正在手动创建bean,而不是让Spring容器创建它。基本上,您正在这样做:

new MyBeanOne()
因此,Spring容器无法注入您配置的任何字段,因此这些字段是
null
,例如
jdbcTemplate
字段。有一些解决方案:

  • SomeOtherClass
    转换为Spring容器管理的bean,并让它注入
    MyBeanOne
    实例(可能使用
    @Autowired
    注释)

  • 如果由于需要手动创建bean而无法使用后一种方法,则可以手动创建bean,如下所示:

    但是这个实现让您硬编码spring配置文件名,并在代码中使用它。因此,更好的方法是选择3

  • 看看这个解决方案:,其中您创建了一个客户机抽象类,其中包含一个方法,Spring将实现该方法来检索Spring托管bean的新实例


  • 我通过使用
    @Configurable
    注释找到了另一种处理方法。通过使用此注释装饰bean,您可以根据需要创建bean的新实例,Spring将为您管理Spring管理的bean的注入。但是为了实现这一点,Spring需要在幕后使用方面,并且您应该为您的项目激活方面的使用。解释相当长,因此我提供了深入解释此解决方案的链接:


    请注意,为了启用此功能,您必须在启动JVM时添加一个java代理,该JVM将在运行时使用方面编织类。

    如注释中所述,问题是您手动创建bean,而不是让Spring容器创建它。基本上,您正在这样做:

    new MyBeanOne()
    
    因此,Spring容器无法注入您配置的任何字段,因此这些字段是
    null
    ,例如
    jdbcTemplate
    字段。有一些解决方案:

  • SomeOtherClass
    转换为Spring容器管理的bean,并让它注入
    MyBeanOne
    实例(可能使用
    @Autowired
    注释)

  • 如果由于需要手动创建bean而无法使用后一种方法,则可以手动创建bean,如下所示:

    但是这个实现让您硬编码spring配置文件名,并在代码中使用它。因此,更好的方法是选择3

  • 看看这个解决方案:,其中您创建了一个客户机抽象类,其中包含一个方法,Spring将实现该方法来检索Spring托管bean的新实例


  • 我通过使用
    @Configurable
    注释找到了另一种处理方法。通过使用此注释装饰bean,您可以根据需要创建bean的新实例,Spring将为您管理Spring管理的bean的注入。但是为了实现这一点,Spring需要在幕后使用方面,并且您应该为您的项目激活方面的使用。解释