spring单例如何改多例

目录
  • spring单例改多例
    • 附加自己待测试
  • spring单例、多例使用方法
    • spring支持的模式
    • 扩展模式

spring单例改多例

单例:就像你一生只有一个老婆。也就是对象始终是同一个。

多例:就像你一生有好多个老婆。也就是对象每次都是新的。

spring默认是单例模式(就每个请求都是用的同一对象,对于dao层肯定是棒棒的),但是有的时候,我们需要每个请求都

产生一个新的对象,就如做微信小程序,用scoket、不可能一直都用一个来接收的,因为需要分配房间,所以需要使用到多例。

对于struts2来说,action必须用多例,因为action本身含有请求参数的值,即可改变的状态;

而对于STRUTS1来说,action则可用单例,因为请求参数的值是放在actionForm中,而非action中的;

配置某个类为多例:

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

但是比如service配置的是多例、dao又是单例,那肯定不行了,因为不能自动注入。

所以需要获得一个新的dao实例,但是手动new的都不可以,那么就借助通过实现 BeanFactoryAware 接口来获得factory

附加自己待测试

public class userService implements BeanFactoryAware{   
  private UserDao userDao;
  private BeanFactory factory;
  public void userService (){
    this.userDao= (UserDao)factory.getBean("userDao");
    userDao.work();
  }
  public UserDao getUserDao() {
        return userDao;
  }
public void setBeanFactory(BeanFactory f) throws BeansException {
    factory = f;
  }
 
}

spring单例、多例使用方法

今天聊聊单例和多例。只想看spring管理的实例有哪些模式,直接看最后。

相信大部分使用java 做web开发的开发人员都用过spring。spring功能最基础功能就是IoC(Inversion of control——控制反转)、AOP(Aspect Oriented Programming——面向切面编程)。其中IoC核心是DI(Dependency injection——依赖注入)。

我们最开始写项目自然而然的是没有框架,生写!但代码多了之后,发现有很多代码,可以抽成公共方法。有些又可以抽成一个类。而有些类又是贯穿整个项目生命周期始终的,而且往往这些类的初始化方法很复杂且重要。那怎么办,总不能每次使用的时候初始化一遍吧,这样很耗编码时间不说,还很占用计算机性能。于是,工厂模式应运而生。通过工厂模式获取各个重要的实例对象。这样就带来一个问题,怎样保证实例只创建一次呢?单例模式应运而生。于是,我们常用的框架spring就成了。

然而需求的发展往往不是单一技术能很好解决的。单例、依赖注入固然好。但是也让我们的开发模式陷入一种定式。即controller、service、dao这样虽然是快速规范的划分,但是往往一些复杂的逻辑只在service或者controller中写会有大量的私有方法、或者一个方法几百上千行。整个业务操作的生命周期局限在一个方法内。并不能好好利用面向对象的思想,写到最后完全就是面向过程编程。一旦逻辑复杂,那方法写的简直惨不忍睹,而且局限于方法的生命周期,很多参数可能会多次调用数据库查同一个数据。那么有什么办法能改变这个局面呢?历史总会给我们答案。

自新世纪之初提出“领域驱动设计”(DDD)以来,这玩意一直不受重视,不仅玄之又玄的理论很少有人去专研,而且所谓“敏捷开发”的盛行,也不适合DDD。但这里并不介绍DDD,说一说DDD的充血模型要在传统数据驱动的业务中使用将面临的首要问题——单例如何注入进充血模型。

比如,我有个User对象,而对象的保存查询操作是与数据库操作。我并不想让User是一个干瘪的值对象,而是让他具备行为,是一个真正有血有肉的充血模型。那么saveUser(User)这样的方法就不再由Dao提供,而是应该由user.save()替代。熟悉JPA的同学肯定想到了。jpa支持对象操作替代传统的repository操作。例如典型的user中的List<Role> roles属性作为关联查询的属性。如果设置级联查询为懒加载,那么jpa只在调用user.getRoles()方法执行的时候发送sql查询对应的role。这是因为jpa代理了user实体对象,而且这也有个问题。如果被jpa代理的对象调用toString()方法,获取roles属性打印时会触发jpa操作。但这时可能已经不属于jpa Entity的生命周期了。踩过坑的朋友肯定遇到过打印日志报了莫名的jpa异常,百思不得其解吧。

况且我们想要的不只是这些。我们可能有些其他的被sqring单例管理的对象方法需要在不同的实例对象中使用。例如:user想要发送数据到远程。那么user.send()可就不归jpa管了。此时如果要想让user能做这个事情必然只能通过spring上下文获取被spring管理的类。聪明的小伙肯定想到了。我让user也被spring管理起来,不就可以注入了吗?是的,但是一旦被spring管理默认就是单例的。总不能每个user都是同一个吧。其实spring可以设置多例的,只是用的人很少。在加有@componet之类注解(@service、@bean...等)受spring管理的类上再加上注解@scope(“prototype”)那么被spring管理的类就是多例的。稍微麻烦点的是,要想获取多例必须通过spring上下文获取。如果直接注入,那么注入的user还是只是那一个。相信各位一定都看过@scope(“prototype”)这种写法吧。但spring其实提供了常量,@scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE),常量可以防止写错那长串单词。有了多例,我们有血有肉的User对象写起来就方便了许多。

为什么我们要这么做呢?“把权力关进笼子”,这句话在编程界就是强类型、常量、枚举这些来体现的。同样,DDD也是把权力锁进领域对象。避免随心所欲的service、随心所欲的repository导致代码后期维护成为爬“屎山”。

spring支持的模式

1.ConfigurableBeanFactory.SCOPE_SINGLETON——单例

2.ConfigurableBeanFactory.SCOPE_PROTOTYPE——多例

扩展模式

3.WebApplicationContext.SCOPE_APPLICATION

4.WebApplicationContext.SCOPE_GLOBAL_SESSION

5.WebApplicationContext.SCOPE_SESSION

6.WebApplicationContext.SOCPE_REQUEST

以上扩展模式看名字都能明白不做多介绍了。希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈Spring 的Controller 是单例or多例

    背景:今天写代码遇到一个Controller 中的线程安全问题,那么Spring 的Controller 是单例还是多例的呢?若为单例又如何保证并发安全呢? 一.面试回答 Spring管理的Controller,即加入@Controller 注入的类,默认是单例的,因此建议: 1.不要在Controller 中定义成员变量:(单例非线程安全,会导致属性重复使用) 2.若必须要在Controller 中定义一个非静态成员变量,则通过注解@Scope("prototype"),将其设置为多

  • Spring bean配置单例或多例模式方式

    目录 Spring bean配置单例或多例模式 单例 多例 Spring scope配置单例.多例模式 1.scope属性介绍 2.scope配置 3.单例模式底层实现模拟 Spring bean配置单例或多例模式 单例 spring bean 默认是单例默认,在对应.xml文件中的配置是: <bean id="user" class="..." scope="singleton"/> singleton就是配置这个bean是否是单例

  • 通过spring注解开发,简单测试单例和多例区别

    目录 通过spring注解开发,测试单例和多例区别 1.注解和配置两种用法形式 2.在spring框架中,scope作用域默认是单例的 3.实例 (1)多例: (2)单例(注解版) Spring中单例和多例的理解 1.什么是单例和多例 2.Spring中的单例与多例 单例bean与多例(原型)bean的区别: 3.单例的优势与劣势 优势: 劣势: 4.spring单例模式与线程安全: 如何解决线程安全问题? 5.单例如何变多例 通过spring注解开发,测试单例和多例区别 1.注解和配置两种用法

  • Spring中单例和多例的深入理解

    Spring单例和多例的理解 1.什么是单例和多例 单例:所有请求用同一个对象来处理.通过单例模式,可以保证系统中一个类只有一个实例. 多例:每个请求用一个新的对象来处理. 2.Spring中的单例与多例 spring ioc容器的bean都是默认单例的,即spring依赖注入Bean实例默认是单例的. spring提供了5中scope,分别是singleton,prototype,request,session,global session,常用是前两种.点此查看官网介绍. 单例bean与多例

  • spring单例如何改多例

    目录 spring单例改多例 附加自己待测试 spring单例.多例使用方法 spring支持的模式 扩展模式 spring单例改多例 单例:就像你一生只有一个老婆.也就是对象始终是同一个. 多例:就像你一生有好多个老婆.也就是对象每次都是新的. spring默认是单例模式(就每个请求都是用的同一对象,对于dao层肯定是棒棒的),但是有的时候,我们需要每个请求都 产生一个新的对象,就如做微信小程序,用scoket.不可能一直都用一个来接收的,因为需要分配房间,所以需要使用到多例. 对于strut

  • 浅谈Spring单例Bean与单例模式的区别

    Spring单例Bean与单例模式的区别在于它们关联的环境不一样,单例模式是指在一个JVM进程中仅有一个实例,而Spring单例是指一个Spring Bean容器(ApplicationContext)中仅有一个实例. 首先看单例模式,在一个JVM进程中(理论上,一个运行的JAVA程序就必定有自己一个独立的JVM)仅有一个实例,于是无论在程序中的何处获取实例,始终都返回同一个对象,以Java内置的Runtime为例(现在枚举是单例模式的最佳实践),无论何时何处获取,下面的判断始终为真: // 基

  • Spring单数据源的配置详解

    目录 前言 一.生成项目骨架(SpringBoot),运行一个简单的程序 二.选择原生Spring方式配置数据源 前言 spring数据源的配置网络上有很多例子,这里我也来介绍一下单数据源配置的例子,基于SpringBoot的方式和原生的Spring的方式. 一.生成项目骨架(SpringBoot),运行一个简单的程序 访问:https://start.spring.io/ ,选择必要的依赖 下面我们先看下Application类的代码: @SpringBootApplication @Slf4

  • vue-cli单页应用改成多页应用配置详解

    前言 从接触vue开始用的是vue-cli直接搭建单页应用,参考配合着vue-router开发起来简直爽到吊炸天,但是由于项目越来越复杂了,单页用起来可能有点力不从心,能不能弄成多页面呢,查了相关资料得到的结论是完全可以的,能多页面多入口,并且可以使用组件,还引入jQuery,这简直完美了,这个demo是从我已经改造完成的项目中摘出来的,现在演示下怎么把基于vue2的vue-cli单页模板改造成多页面,并且多入口的项目. 技术栈 vue: 2.0.1 vue-resource:1.0.3 vue

  • Spring中Bean的单例和多例使用说明

    目录 Bean的单例和多例使用 实战演示 Spring单例bean与原型bean区别和创建过程 singletonScope与prototypeScope Bean的单例和多例使用 在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例) singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例. prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new. Spring

  • 关于spring中单例Bean引用原型Bean产生的问题及解决

    目录 spring单例Bean引用原型Bean产生的问题及解决 问题描述 为了更直观的发现问题,下面我们用代码演示一遍 问题分析 spring Bean的几个相关问题 1.Spring Bean 作用域 2.什么是Spring inner beans 3.什么是有状态.无状态 4.Spring框架中的单例Bean是线程安全的么 5.Spring Bean 的自动装配 6.各种自动装配模式的区别 7.在Spring中可以注入null或空字符串吗 8.Spring框架中有哪些不同类型的事件(都继承自

  • 初识Spring Boot框架和快速入门

    前面的铺垫文章已经连着写了六篇了,主要是介绍了spring和SpringMVC框架,小伙伴们在学习的过程中大概也发现了这两个框架需要我们手动配置的地方非常多,不过做JavaEE开发的小伙伴们肯定也听说过"约定大于配置"这样一句话,就是说系统,类库,框架应该假定合理的默认值,而非要求提供不必要的配置,可是使用Spring或者SpringMVC的话依然有许多这样的东西需要我们进行配置,这样不仅徒增工作量而且在跨平台部署时容易出问题.OK,由于这些已经存在的问题,Spring Boot应运而

  • spring在IoC容器中装配Bean详解

    1.Spring配置概述 1.1.概述 Spring容器从xml配置.java注解.spring注解中读取bean配置信息,形成bean定义注册表: 根据bean定义注册表实例化bean: 将bean实例放入bean缓存池: 应用程序使用bean. 1.2.基于xml的配置 (1)xml文件概述 xmlns------默认命名空间 xmlns:xsi-------标准命名空间,用于指定自定义命名空间的schema文件 xmlns:xxx="aaaaa"-------自定义命名空间,xx

随机推荐