spring生成对象默认是单例的。通过scope属性可以更改为多例。

<bean id="user" class="modle.User" scope="prototype">
</bean>

现在又这么一种情况.

User类调用一个service, 这个service又调用一个tool。

有时我们希望User是多例的,service是单例的,而tool又是多例的。

很自然地想法是配置文件这些写

<bean id="user" class="modle.User" scope="prototype">
<property name="service" ref="userservice"></property>
</bean> <bean id="userservice" class="service.userService" >
<property name="tool" ref="tool"></property>
</bean> <bean id="tool" class="service.ToolImpl" scope="prototype"></bean>

但是这种写法是错误的! 不能使用spring的自动注入!

由于service是单例的,所以这种方法的结果是:User多例,service和tool都是单例。(为什么?)

官网文档:

4.5.3 Singleton beans with prototype-bean dependencies

When you use singleton-scoped beans with dependencies on prototype beans, be aware that dependencies are resolved at instantiation time. Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.

However, suppose you want the singleton-scoped bean to acquire a new instance of the prototype-scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into your singleton bean, because that injection occurs only once, when the Spring container is instantiating the singleton bean and resolving and injecting its dependencies. If you need a new instance of a prototype bean at runtime more than once, see Section 4.4.6, “Method injection”

正确的写法是,是每次调用tool时都生成一个新的tool对象。但是我们又不能手动new一个,要借助BeanFactory

public class User {

	private userService service;
private int age;
private Date date;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public userService getService() {
return service;
}
public void setService(userService service) {
this.service = service;
} }

UserService 通过实现 BeanFactoryAware 接口来获得factory

由于不使用spring的自动注入,set方法要去掉!

public class userService implements BeanFactoryAware{

	private Tool tool;
private BeanFactory factory;
public void service(){
this.tool = (Tool)factory.getBean("tool");
System.out.println(this+":service");
tool.work();
}
public Tool getTool() { return tool;
}
// public void setTool(Tool tool) {
//
// this.tool = (Tool)factory.getBean("tool");
// }
public void setBeanFactory(BeanFactory f) throws BeansException {
factory = f;
} }

配置文件,不能再使用注入。因此要把tool对象的注入去掉!

<bean id="user" class="modle.User" scope="prototype">
<property name="service" ref="userservice"></property>
</bean> <bean id="userservice" class="service.userService" >
</bean> <bean id="tool" class="service.ToolImpl" scope="prototype"></bean>
public interface Tool {
public void work();
}
public class ToolImpl implements Tool{

	public void work() {
System.out.println(this+":Tool Work");
} }

测试类:

public class Test {
public static void main(String[] args) {
ClassPathResource res = new ClassPathResource("applicationContext.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
User user = (User)factory.getBean("user");
User user2 = (User)factory.getBean("user"); System.out.println(user);
user.getService().service();
System.out.println();
System.out.println(user2);
user2.getService().service();
}
}

Output:

modle.User@42552c
service.userService@19e15c:service
service.ToolImpl@11a75a2:Tool Work
modle.User@210b5b
service.userService@19e15c:service
service.ToolImpl@170888e:Tool Work

原文  http://blog.csdn.net/gaotong2055/article/details/8245036

 

(转载)spring单例和多例详解。如何在单例中调用多例对象的更多相关文章

  1. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

  2. 使用Squid做代理服务器,Squid单网卡透明代理配置详解(转)

    使用Squid做代理服务器 说到代理服务器,我们最先想到的可能是一些专门的代理服务器网站,某些情况下,通过它们能加快访问互联网的速度.其实,在需要访问外部的局域网中,我们自己就能设置代理,把访问次数较 ...

  3. (转载)完成端口(Completion Port, I/OCP)详解

    http://www.cnblogs.com/lancidie/archive/2011/12/19/2293773.html 手把手叫你玩转网络编程系列之三    完成端口(Completion P ...

  4. 2017.2.13 开涛shiro教程-第十二章-与Spring集成(一)配置文件详解

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十二章-与Spring集成(一)配置文件详解 1.pom.xml ...

  5. 【Spring】——声明式事务配置详解

    项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...

  6. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  7. Spring Boot的每个模块包详解

    Spring Boot的每个模块包详解,具体如下: 1.spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. 2.spring-boot-s ...

  8. idea spring+springmvc+mybatis环境配置整合详解

    idea spring+springmvc+mybatis环境配置整合详解 1.配置整合前所需准备的环境: 1.1:jdk1.8 1.2:idea2017.1.5 1.3:Maven 3.5.2 2. ...

  9. spring boot 配置文件properties和YAML详解

    spring boot 配置文件properties和YAML详解 properties中配置信息并获取值. 1:在application.properties配置文件中添加: 根据提示创建直接创建. ...

  10. Spring全家桶——SpringBoot之AOP详解

    Spring全家桶--SpringBoot之AOP详解 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方 ...

随机推荐

  1. 洛谷P1040 加分二叉树【记忆化搜索】

    题目链接:https://www.luogu.org/problemnew/show/P1040 题意: 某一个二叉树的中序遍历是1~n,每个节点有一个分数(正整数). 二叉树的分数是左子树分数乘右子 ...

  2. 排查 docker flow proxy 的 503 问题

    这是今天我们在开发环境下 docker swarm 集群上遇到的问题,在这篇博文中记录一下排查过程. 先登录到应用容器内检查一下其中运行的站点是否能正常访问: # docker exec -it 02 ...

  3. Ubuntu16.04下安装QT5.8

    https://blog.csdn.net/hhrock/article/details/61621044

  4. jdbc --- javabean

    第一部分: javaBean 类  要和数据库表的字段一一对应 package com.ljs.bean; public class UserBean { private int id; privat ...

  5. tensorflow scope的作用

    我们在使用tensorflow的时候,当你想复用一个函数的模块,调试时候回提示你变量已经出现,提示你是否重用.那我们当然是不重用的,因为每一个变量都是我们需要的. 要体现不同,就在不同的变量中使用na ...

  6. Uniform Resource Name Server

    HTTP The Definitive Guide 按址标识 identify by address 按名标识 identify by name Domain Name Server Uniform ...

  7. Web发展简史

    World Wide Web--万维网,常指网页,网站 发展至今仅30年(1989-2019) Tim Berners-Lee(蒂姆.伯纳斯.李)英国计算机科学家,万维网的发明者. 1990年Tim ...

  8. javascript高级技巧篇(作用域安全、防篡改、惰性载入、节流、自定义事件,拖放)

    安全的类型检测 在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式字符串.每个类在内部都有一个[[Class]]属性 ...

  9. 第四章:初识CSS3

    1.CSS规则由两部分构成,即选择器和声明器 声明必须放在{}中并且声明可以是一条或者多条 每条声明由一个属性和值构成,属性和值用冒号分开,每条语句用英文冒号分开 注意: css的最后一条声明,用以结 ...

  10. 集成xxl-job分布式任务调度平台

    首先声明,本篇博文基于springboot,基于spring的请自行研究. (一)启动控制平台 首先将xxl-job-master.zip下载下来,然后在mysql数据库创建xxl-job数据库. 执 ...