由于看淘淘商城的项目,涉及到了项目中处理spring中bean对象的两种类型,分别是单例和多例,就在此记录一下,方便加深理解,写出更加健壮的代码。

一、单例和多例的概述

在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)。所谓单例,就是所有的请求都由一个对象来进行处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理。

singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例。不管new多少次,只生成一个对象。
prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new。

二、为什么使用单例或多例

  之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;之所以用多例,是为了防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理。
  用单例和多例的标准只有一个:当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例。就如dao和service这两层的数据一般不会有相应的属性修改,所以可以考虑用单例,而Controller层会存储很多需要操作的vo类(value object值对象),此时这个对象的状态就会被改变,就要使用多例。

三、如何使用多例

  这里是指定的特定场景下,就是记录一下,其中涉及到的一小点,先说一下,在什么情况下使用的这个spring中的bean的多例模式,就是项目中前台web项目需要使用HttpClient连接访问后台的接口地址,在使用HttpClient的过程中,涉及到连接的各种配置以及HttpClient连接池的使用,我们把一些公用的配置以及连接池,HttpClient构造器等一些配置,配置到单独的配置文件中,spring容器自己创建、管理这些对象,我们只需要注入这些对象就可以使用了,是不是很方便。这也是优化代码的一种方式,抽取出公共的部分,交由spring管理,这其中涉及到了RequestConfig(请求HttpClient连接的配置文件,这个是单例的)、CloseableHttpClient(HttpClient连接对象,这个要设计成多例的,在调用同一个方法时会创建不同的HttpClient对象)

注意:多例对象在使用的时候是不可以用注入的方式的@Autowired

具体解决办法是:实现BeanFactoryAware接口,重写setBeanFactory()方法,在spring容器初始化时传入BeanFactory,通过BeanFactory创建HttpClient连接对象

 package com.taotao.web.service;

 import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.taotao.web.httpclient.HttpResult; @Service
public class ApiService implements BeanFactoryAware{ @Autowired
private RequestConfig requestConfig; private BeanFactory beanFactory; private CloseableHttpClient getHttpClient(){
return this.beanFactory.getBean(CloseableHttpClient.class);
} @Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//该方法是在spring容器初始化时调用,传入beanFactory
this.beanFactory = beanFactory;
}
}

Spring对象类型——单例和多例的更多相关文章

  1. Spring中的单例一二

    Spring框架很好的帮助我们创建和管理dao.bean.service.action等对象, 但是它创建的对象是单例呢还是多例,又有哪些区别以及为什么 1.在Spring中默认创建的是单例模式,简单 ...

  2. spring自动注入是单例还是多例?单例如何注入多例?

       单例和多例的区别 :   单例多例需要搞明白这些问题:      1. 什么是单例多例:      2. 如何产生单例多例:      3. 为什么要用单例多例      4. 什么时候用单例, ...

  3. spring如何解决单例循环依赖问题?

    更多文章点击--spring源码分析系列 1.spring循环依赖场景2.循环依赖解决方式: 三级缓存 1.spring循环引用场景 循环依赖的产生可能有很多种情况,例如: A的构造方法中依赖了B的实 ...

  4. Spring IOC - 控制反转(依赖注入) - 单例和多例

    Spring容器管理的bean在默认情况下是单例的,即一个bean只会创建一个对象,存在map中,之后无论获取多少次该bean,都返回同一个对象. Spring默认采用单例方式,减少了对象的创建,从而 ...

  5. Spring课程 Spring入门篇 4-7 Spring bean装配之基于java的容器注解说明--@Scope 控制bean的单例和多例

    1 解析 1.1 bean的单例和多例的应用场景 1.2 单例多例的验证方式 1.3 @Scope注解单例多例应用 2 代码演练 2.1 @Scope代码应用 1 解析 1.1 bean的单例和多例的 ...

  6. spring的controller默认是单例还是多例

    转: spring的controller默认是单例还是多例 先看看spring的bean作用域有几种,分别有啥不同. spring bean作用域有以下5个: singleton:单例模式,当spri ...

  7. Spring 的Controller 是单例or多例

    Spring 的Controller 是单例or多例 你什么也不肯放弃,又得到了什么? 背景:今天写代码遇到一个Controller 中的线程安全问题,那么Spring 的Controller 是单例 ...

  8. Java单例和多例

    背景:最近在学习韩老师的笔记时候发现不是很了解单例和多例,于是通过网上查找资料的方式去学习. 设计模式:最佳的实践,是软件开发人员在软件开发过程中面临一般解决方案,也就是开发的经验总结. 单例模式(S ...

  9. springboot默认创建的bean是单实还是多例

    转:https://blog.csdn.net/q1512451239/article/details/53122687 springboot默认创建的bean是单实还是多例 曾经面试的时候有面试官问 ...

随机推荐

  1. word-break word-wrap

    work-break:break-all CJK超出的部分自动换行 word-wrap:break-word CJK如果有分隔符,当前分隔符之后与下一个分隔符之间的内容不能在这一行全部显示的话,在当前 ...

  2. Python解压缩ZIP格式

    转自:http://blog.csdn.net/linux__kernel/article/details/8271326 很多人在Google上不停的找合适自己的压缩,殊不知Py的压缩很不错.可以试 ...

  3. Linq list 排序,Dictionary 排序

    C# 对List成员排序的简单方法 http://blog.csdn.net/wanzhuan2010/article/details/6205884 LINQ之路系列博客导航 http://www. ...

  4. Node 基本使用

    node -v:查看node版本 npm -v:查看npm版本 npm install npm -g :升级npm版本 npm install <module_name> [-g]:安装指 ...

  5. SQL Server 语法注意

    1.order by select a1,a1 from  temp order by a1 此语句在高版本中执行提示a1列名不明确,在低版本中执行成功!

  6. Jedis线上的一个小坑:Redis有并发访问的数据错乱的问题

    问题现象: 业务数据有错乱,A的一些数据有好几个都是B的数据 这些业务数据在保存在Redis缓存中,怀疑是并发情况下Jedis错乱的问题 原因分析: JedisUtil里面在使用完Jedis 后释放资 ...

  7. header的参数不能带下划线

    移动端把一些公共参数放在了 header 了, 在 laravel 中使用 use \Illuminate\Http\Request; //这个是获取所有header信息Request::header ...

  8. springMVC RedirectAttributes

    @Controller public class TestController { @RequestMapping("/redirectDemo") public String r ...

  9. docker数据存储

    docker数据存储 docker提供了三种类型的数据存储 第一种:将数据直接存储在容器中 第二种:将数据映射到外部的本机目录 第三种:将数据映射到专门的数据卷容器

  10. [ZPG TEST 111] 奶牛的新家【DP】

    3.奶牛的新家 [问题描述] 由于奶牛们纷纷表示破旧的房子实在是太丑陋了,DD决定给他们建造新家.现在有许多奶牛决定将家建造在n*m的城市中.然而奶牛们分成了k帮派,不同帮派的奶牛不能住在同列或同行上 ...