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. IIS8.5 Error Code 0x8007007e HTTP 错误 500.19的解决方法

    window server 2012R2 IIS8.5 引用:https://www.52jbj.com/yunying/340443.html HTTP 错误 500.19 - Internal S ...

  2. eclipse 注销和取消注销

    单行注释: CTRL + / 当行取消注释(一样的): CTRL + / 多行注释: CTRL + SHIFT + / 多行取消注释(斜杠换成反斜杠): CTRL + SHIFT + \

  3. phpstorm之ssh链接远程Linux服务器

    save ssh session inPHPstorm. open PHPstorm,open File,> Settings >search for 'Deployment' > ...

  4. AutoMapper介绍(未完待续、部分没实现)

    实体间转换工具.其实也可以用Json来实现同名属性.异名属性(用JsonProperty指明)的自动转换 最新版本6.11 需要使用vs2013以上.vs2012下载新版 nuget会遇到问题.只能旧 ...

  5. [knowledge][perl][pcre][sed] sed / PCRE 语法/正则表达式

    一直用sed一直没有正经的学过语法,一直一知半解的用着. 因为,它用来perl的语法,要想搞懂,首先要搞懂perl,系统的入个门... 之前,man sed,man了好多次,总是没找到关键内容,今天在 ...

  6. [httpd] httpd directory list character encoding

    在httpd下放置文件用来直接从浏览器访问的时候,中文文件名有可能产生乱码. 做以下设置,调整字符编码: 1: Add this to your .htaccess: IndexOptions +Ch ...

  7. DBCHART直方图顶端显示数字

    双击DBCHART-->选SERIES选项卡-->选MARKS-->选STYLE值为VALUE

  8. linux常用查看文件或日志命令

    常见查看文件内容命令汇总如下: cat     filename           查看日志,会打开整个文件,直接跑到最后面 tac     filename           查看日志,会打开整 ...

  9. python编码类型互转总结

    1.只有在unicode下才能将utf-8与gbk互转2.unicode是在内存中使用,bytes是文件存储和网络传输时使用-------------------------------------- ...

  10. es6学习一 promise上

    简单来说promise在异步操作上提供可读性.(原来es5的异步操作可读性实在太糟糕了,如下图) 瞬间眼前百万只奔腾的马,只不过这种马有个别名,羊驼. 一.创建形式 1. 使用的基本形式: let p ...