@Autowired 会话范围 bean 不指向同一个实例
@Autowired session scope bean not pointing to same instance
我在 spring 中自动装配 bean 时遇到了这种奇怪的情况。首先我声明这个bean;
<beans:bean id="customerInfo" class="my.web.app.com.CustomerInfoSession" scope="session" >
<aop:scoped-proxy />
</beans:bean>
当我在 customerInfo;
中设置值时有两种情况
首先我是这样设置的:
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
然后我通过@Autowired bean 检查另一个class 中的Autowiring 指针;
在测试中 class:
@Controller
public class Test {
@Autowired
private CustomerInfoSession customerInfo;
public void checkObject(){
System.out.println("Call back : "+customerInfo);//for second pointing check
}
}
结果:
Instance : my.web.app.com.CustomerInfoSession@1e7c92cc
Call back :my.web.app.com.CustomerInfoSession@1e7c92cc
正如我们所见,@Autowiring 正在调用同一个 bean 实例,但当我更改为这样设置值时,问题就来了:
customerInfo = (CustomerInfoSession) jdbcTemplate.queryForObject(query,qparam,new BeanPropertyRowMapper<>(CustomerInfoSession.class));
System.out.println("Instance : "+customerInfo);//for first pointing check
通过使用相同的测试 class,结果 是:
Instance : my.web.app.com.CustomerInfoSession@2d700bd6
Call back :my.web.app.com.CustomerInfoSession@5e33e39c
正如我们所见,@Autowired 没有指向同一个实例...
为什么使用不同的 jdbc 模板会影响 @Autowired 会话作用域 bean?
为什么 bean 没有像应该的那样指向同一个实例?
在第一种情况下,您正在设置由 Spring 注入的对象的属性。
但在下一种情况下,jdbcTemplate
正在创建 CustomerInfoSession
对象的新实例,您已将 customerInfo
对象引用指向这个新创建的对象。
下面的语句
customerInfo = (CustomerInfoSession) jdbcTemplate.queryForObject(query,qparam,new BeanPropertyRowMapper<>(CustomerInfoSession.class));
实际上等同于
CustomerInfoSession temp = (CustomerInfoSession)
jdbcTemplate.queryForObject(query, qparam,
new BeanPropertyRowMapper<>(CustomerInfoSession.class));
customerInfo = temp;
可视化(点击下面的图片可以更好地查看),
情况一:
案例2:
我在 spring 中自动装配 bean 时遇到了这种奇怪的情况。首先我声明这个bean;
<beans:bean id="customerInfo" class="my.web.app.com.CustomerInfoSession" scope="session" >
<aop:scoped-proxy />
</beans:bean>
当我在 customerInfo;
中设置值时有两种情况首先我是这样设置的:
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
然后我通过@Autowired bean 检查另一个class 中的Autowiring 指针;
在测试中 class:
@Controller
public class Test {
@Autowired
private CustomerInfoSession customerInfo;
public void checkObject(){
System.out.println("Call back : "+customerInfo);//for second pointing check
}
}
结果:
Instance : my.web.app.com.CustomerInfoSession@1e7c92cc
Call back :my.web.app.com.CustomerInfoSession@1e7c92cc
正如我们所见,@Autowiring 正在调用同一个 bean 实例,但当我更改为这样设置值时,问题就来了:
customerInfo = (CustomerInfoSession) jdbcTemplate.queryForObject(query,qparam,new BeanPropertyRowMapper<>(CustomerInfoSession.class));
System.out.println("Instance : "+customerInfo);//for first pointing check
通过使用相同的测试 class,结果 是:
Instance : my.web.app.com.CustomerInfoSession@2d700bd6
Call back :my.web.app.com.CustomerInfoSession@5e33e39c
正如我们所见,@Autowired 没有指向同一个实例...
为什么使用不同的 jdbc 模板会影响 @Autowired 会话作用域 bean?
为什么 bean 没有像应该的那样指向同一个实例?
在第一种情况下,您正在设置由 Spring 注入的对象的属性。
但在下一种情况下,jdbcTemplate
正在创建 CustomerInfoSession
对象的新实例,您已将 customerInfo
对象引用指向这个新创建的对象。
下面的语句
customerInfo = (CustomerInfoSession) jdbcTemplate.queryForObject(query,qparam,new BeanPropertyRowMapper<>(CustomerInfoSession.class));
实际上等同于
CustomerInfoSession temp = (CustomerInfoSession) jdbcTemplate.queryForObject(query, qparam, new BeanPropertyRowMapper<>(CustomerInfoSession.class));
customerInfo = temp;
可视化(点击下面的图片可以更好地查看),
情况一:
案例2: