Spring将数据源bean注入或自动装配到类

Jay*_*Mie 1 java spring jdbc autowired

这可能是一个非常新手的问题,但我已经搜索过,或者我的理解中存在很大差距,或者我做错了一些我无法弄清楚的事情.

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

<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>
Run Code Online (Sandbox Code Playgroud)

现在在myBeanOne我有:

private DataSource dataSource;

private JdbcTemplate jdbcTemplate;

@Autowired
public void setDataSource (DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
}

public void myMethod() {
    String sql = "'My generic SQL update query'";
    try {
        this.jdbcTemplate.update(sql);
    } catch (org.springframework.dao.EmptyResultDataAccessException ex) {
    }
    System.exit(0);
}
Run Code Online (Sandbox Code Playgroud)

当我尝试在调用setDataSource的行上执行此操作时,我收到此错误:

ERROR org.springframework.integration.handler.LoggingHandler 
    org.springframework.integration.MessageHandlingException: 
       java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)

在线上: this.jdbcTemplate.update(sql);

我尝试了十种不同的配置来实现这一点,但我似乎无法做到这一点.非常感谢您的帮助,谢谢.

编辑:根据Luiggi的评论:

//in yet another classes run method
myBeanOne bOne = SomeOtherClass.create();   //just returns new myBeanOne
bOne.myMethod();
Run Code Online (Sandbox Code Playgroud)

SomeOtherClass或此类都不会在上下文中被归类为bean,也不会在上下文中存在.

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

感谢您的耐心等待.

Lui*_*oza 5

正如评论中所指出的,问题是您手动创建bean而不是让Spring容器创建它.基本上,你这样做:

new MyBeanOne()
Run Code Online (Sandbox Code Playgroud)

因此Spring容器不能注入您配置的任何字段,null例如jdbcTemplate字段.有一些解决方案:

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

  2. 如果由于需要手动创建bean 而无法完成后一种方法,则可以手动创建bean,如下所示:如何动态创建spring bean?

    但是这个实现使你在弹簧配置文件名的某处硬编码并在你的代码中使用它.因此,更好的方法是选项3.

  3. 看看这个解决方案:按需创建新的Spring Bean,您可以使用Spring实现的方法创建客户端抽象类,以检索Spring托管bean的新实例.


我找到了另一种使用@Configurable注释来处理这个问题的方法.通过使用此批注装饰bean,您可以根据需要创建bean的新实例,Spring将为您管理Spring托管bean的注入.但要实现这一点,Spring需要在幕后使用方面,您应该激活项目方面的使用.解释很长,所以我提供的链接深入解释了这个解决方案:

请注意,为了启用此功能,您必须在启动JVM时添加Java代理,该JVM将在运行时使用方面编写类.