Java @自动连线会话作用域bean不指向同一实例

Java @自动连线会话作用域bean不指向同一实例,java,spring,autowired,spring-jdbc,jdbctemplate,Java,Spring,Autowired,Spring Jdbc,Jdbctemplate,我在春天自动连接豆子时遇到了这种奇怪的情况。首先我声明这个豆子 <beans:bean id="customerInfo" class="my.web.app.com.CustomerInfoSession" scope="session" > <aop:scoped-proxy /> </beans:bean> 然后我通过@autowiredthebean检查另一个类中的Autowired指针 在测试班: @Controller public cl

我在春天自动连接豆子时遇到了这种奇怪的情况。首先我声明这个豆子

<beans:bean id="customerInfo" class="my.web.app.com.CustomerInfoSession" scope="session" >
    <aop:scoped-proxy />
</beans:bean>
然后我通过@autowiredthebean检查另一个类中的Autowired指针

在测试班:

@Controller
public class Test {

@Autowired
private CustomerInfoSession customerInfo;

public void checkObject(){
System.out.println("Call back : "+customerInfo);//for second pointing check
}

}
结果

实例:my.web.app.com。CustomerInfoSession@1e7c92cc

回拨:my.web.app.com。CustomerInfoSession@1e7c92cc

正如我们所看到的,@Autowiring正在调用它应该调用的同一个bean实例,但是当我更改设置如下值时,问题出现了:

SqlRowSet srs =jdbcTemplate.queryForRowSet(query, qparams);
    if (srs.isBeforeFirst()==true) {
        while (srs.next()) {
            customerInfo.setLoginId(srs.getString("LOGINID"));
            customerInfo.setCompanyId(srs.getString("COMPANYID"));
        }
    }
System.out.println("Instance : "+customerInfo);//for first pointing check
customerInfo = (CustomerInfoSession) jdbcTemplate.queryForObject(query,qparam,new BeanPropertyRowMapper<>(CustomerInfoSession.class));
System.out.println("Instance : "+customerInfo);//for first pointing check
customerInfo=(CustomerInfoSession)jdbcTemplate.queryForObject(query,qparam,newbeanpropertyrowapper(CustomerInfoSession.class));
System.out.println(“实例:+customerInfo”)//用于第一次定点检查
通过使用相同的测试类别,结果为:

实例:my.web.app.com。CustomerInfoSession@2d700bd6

回拨:my.web.app.com。CustomerInfoSession@5e33e39c

正如我们所看到的,@Autowired没有指向同一个实例

为什么使用不同的jdbc模板会影响@Autowired会话范围bean


为什么bean没有像应该的那样指向同一个实例?

在第一个场景中,您正在设置Spring注入的对象的属性

但是在下一种情况下,
jdbcTemplate
正在创建
CustomerInfoSession
对象的一个新实例,您已经将
customerInfo
对象引用指向了这个新创建的对象

下面的陈述

customerInfo=(CustomerInfoSession)jdbcTemplate.queryForObject(query,qparam,newbeanpropertyrowapper(CustomerInfoSession.class))

实际上相当于

CustomerInfo会话临时=(CustomerInfo会话) jdbcTemplate.queryForObject(查询,qparam, 新BeanPropertyRowMapper(CustomerInfoSession.class))

customerInfo=温度

要可视化(单击下面的图像以更好地查看)

在案例1中:

在案例2中:


我不明白。在第一种情况下,Spring上下文为您提供了一个对象。在第二种情况下,
JdbcTemplate
可能从数据库中获取一些数据,并创建并返回一个不同的对象。您的困惑在哪里?@Pillar,第一种情况,我使用setter从数据库中获取的SqlRowSet结果逐个设置
customerInfo
属性,第二种情况,我直接使用BeanPropertyRowMapper设置
customerInfo
,它返回
customerInfo
实例,其属性已使用BeanPropertyRowMapper设置。我的困惑是,当我直接设置对象时,bean没有使用相同的实例,但当我手动设置属性时,它工作得很好。抱歉,评论太长了……您的第二个代理覆盖了会话范围代理,基本上正在销毁会话范围对象,现在它突然变成了一个单例对象。因此,基本上,您在第二部分中所做的是错误和危险的,必须避免。@M.Deinum,实际上我认为
@Autowired
将引用新的bean引用,但不是。毕竟,我只是想简化代码。如果您有任何方法可以简化bean集属性,我将非常感谢您与我分享,顺便说一句,谢谢,用于指出这一点。
@Autowired
用于在启动时连接bean实例,而不是在运行时,并且它不会神奇地将依赖关系导出到其他实例。只需编写一个设置属性的
RowMapper
,而不用
beanpropertyrowapper
。谢谢!因此,它创建了一个新实例。我认为BeanPropertyRowMapper可以简化我的代码。除了我的第一种方法之外,您有没有其他方法可以用来简化jdbctemplate数据库获取?