资讯专栏INFORMATION COLUMN

spring bean scope简要说明,有代码示例

DDreach / 1643人阅读

摘要:之前一直只知道有作用域,没有怎么关注具体内容,今天特意看了,记录过程以作备忘。

之前一直只知道spring bean有作用域,没有怎么关注具体内容,今天特意看了,记录过程以作备忘。

作用域(5类)

作用域总计5种:singleton, prototype, request, session, global session
其中singleton, prototype为常规bean中都可以使用,默认为singleton;request, session, global session为web中特有,主要配置在如controller,action中具体配置方式有多种,此例中以springboot为示例

单例模式(singleton)

spring 容器中只存在一个具体实例,如
定义UserServiceImpl

@Service
public class UserServiceImpl implements IUserService {}
@RestController
@RequestMapping("/user")
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    @Autowired
    private IUserService userService;

    @RequestMapping("/{id}")
    @ResponseBody
    public User get(@PathVariable(required = false) Long id) {
        logger.info("userService:{}", userService.toString());
        return userService.get(1l);
    }
}

@RestController
@RequestMapping("/test")
public class TestController {
    private static final Logger logger = LoggerFactory.getLogger(TestController.class);
    @Autowired
    private IUserService userService;

    @GetMapping("/user")
    public User testUser() {
        logger.info("testController:{}", this.toString());
        logger.info("userService:{}", userService.toString());
        return userService.get(1l);
    }
}
结果:在调用两个地址后,userService.toString()打印出来的结果是一致的

原型模式(prototype) 每次注入时提供一个新的实例

代码如下:
改变服务提供方 UserServiceImpl

@Service
@Scope(value = "prototype")
public class UserServiceImpl implements IUserService {}

再次调用

结果:为两个调用者生成不同的实例,但同一个调用者只生成一个

每次调用时生成不同的实例

可在scope中加入 proxyMode= ScopedProxyMode.TARGET_CLASS

改变服务提供方 UserServiceImpl

@Service
@Scope(value = "prototype",proxyMode= ScopedProxyMode.TARGET_CLASS)
public class UserServiceImpl implements IUserService {}

再次调用

结果:每一次请求(调用),生成了不同的实例

2018-3-26更新开始

如果调用者为原型模式,即

@Scope(value = "prototype")
public class UserController {...}

UserServiceImpl 设置为@Scope(value = "prototype")即可,无需配置proxyMode= ScopedProxyMode.TARGET_CLASS

2018-3-26更新结束
request

request, session, global session为web中特有,作用域大致对应HTTP中的Request, Session和Application,本例只以request为例

保持上面代码修改UserController,代码如下:

@RestController
@RequestMapping("/user")
@Scope(value = "request")
public class UserController {
...
}

再次调用

结果:每次调用会生成新的UserController 实例

@Scope(value = "request") 只能用于 controller/restcontroller 类似web组件中,如用于service中会出现如下异常:
Error creating bean with name "userServiceImpl": Scope "request" is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
另singleton的bean引用一个prototype的bean的说明

网络中有说singleton的bean不能引用prototype的bean,经实验,是可以引用,但能力有限,未能明确引用是否会有线程安全或其他问题
此处仅做引用示例,代码如下

修改UserController,代码如下:

@RestController
@RequestMapping("/user")
public class UserController {
...
}

修改

@Service
@Scope(value = "prototype",proxyMode= ScopedProxyMode.TARGET_CLASS)
public class UserServiceImpl implements IUserService {}

再次调用

结果:在singleton的bean可以引用prototype的bean

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76341.html

相关文章

  • spring入门指南

    摘要:装配提供了三种装配机制在中进行显示配置在中进行显示配置隐式的发现机制和自动装配机制。表示该类是一个组件,将自动创建该组件实例,表示注入组件实例,和功能类似,和功能类似,但和是规范中提供的注解。 基本原理 spring的基础是IOC和DI,其实IOC和DI是对同一件事从不同的方面进行描述的,两者在spring中是同一件事务。 IOC:控制反转,在这里就是指创建bean的主动权发生了转移,...

    shusen 评论0 收藏0
  • Spring详解3.Bean的装配

    摘要:的依赖关系,根据依赖关系配置完成之间的装配。的行为信息,如生命周期范围及生命周期各过程的回调函数。使用该种装配模式时,优先匹配参数最多的构造函数。如果提供了默认的构造函数,则采用否则采用进行自动装配。 点击进入我的博客 1 Spring容器与Bean配置信息 Bean配置信息 Bean配置信息是Bean的元数据信息,它由一下4个方面组成: Bean的实现类 Bean的属性信息,如数...

    endiat 评论0 收藏0
  • Spring Boot [组件学习-Spring]

    摘要:框架最初是由编写的,并且年月首次在许可下发布。在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知在建议方法调用之前和之后,执行通知。方法执行之后,不考虑其结果,执行通知。 导读: 在上篇文章的结尾提到了Spring Boot 提供了一系列的框架整合(Starter POMs)帮助我们提升开发效率,但是这并不意味着我们不需要学习这些框架,反而更需要去学习,通过学习这些框架可以使...

    raoyi 评论0 收藏0
  • Spring5:@Autowired注解、@Resource注解和@Service注解[转载]

    摘要:因此,引入注解,先看一下配置文件怎么写注意第行,使用必须告诉一下我要使用注解了,告诉的方式有很多,是一种最简单的,会自动扫描路径下的注解。 什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop、事物,这么做有两个缺点: 1、如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。总之...

    netScorpion 评论0 收藏0
  • Spring Boot 参考指南(安全)

    摘要:用于发布身份验证事件的。导入用于安全,配置身份验证,这在非应用程序中也是相关的。安全出于安全考虑,除和之外的所有默认禁用,属性可用于启用。有关保护的其他信息可以在参考指南中找到。 28. 安全 如果在类路径上有Spring Security,那么web应用程序默认是安全的,Spring Boot依赖Spring Security的内容协商策略来决定是使用httpBasic还是formL...

    XanaHopper 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<