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数据库获取?