Spring Framework支持五种作用域,如下图所示:

singleton:表示一个容器中只会存在一个bean实例,无论在多少个其他bean里面依赖singleton bean,整个容器都只会存在一个实例。相当于是容器的全局变量。

prototype:一个容器中可能会存在多个bean实例,prototype bean的实例产生有两种情况,一种是其他bean请求依赖prototype 容器会为其他bean分别创建一个实例。另外一种就是通过ApplicationContextAware 接口的 getBean方法获取 bean的时候 容器也会创建一个新的实例。

request:这个不用多说,即容器会为每一个HTTP请求都会创建一个实例。

session:容器会为每个session创建一个bean实例

那么问题来了,由于bean的作用域不同,其实例创建的时间也不会相同,如果程序中存在一个 singleton bean 依赖了一个 request bean ,直接通过 @Autowired注解项目在启动的时候会报错的,如何解决这个问题呢?Spring 提供了lookup-method方法来解决这个问题。下面来看一个例子:

1 首先新建一个User类

public class User {

private String name;

private String password;

private int age;
//省略setter 和 getter
}
2 将这个User类注册成为 request 作用域的bean 在springContext.xml文件中
<bean id="user" class="com.zsq.cn.login.entity.User" scope="request">
<property name="name" value="zsq" />
</bean>
3 新建一个controller
@Controller
public class LoginController extends BaseException{
@Autowired
private LookupMethodService lookupMethodService;

@RequestMapping("/")
public String home(Model model){
User user = lookupMethodService.getUser();
System.out.println(user.toString());
return "home/index";
}
}
4 新建一个service 以及其实现类
public interface LookupMethodService {

User getUser();
}

@Service
public abstract class LookupMethodServiceImpl implements LookupMethodService {

@Override
public User getUser() {
return creatUser();
}

public abstract User creatUser();
}
5 在springContext.xml文件中配置

<bean id="lookupMethodServiceImpl" class="com.zsq.cn.login.service.impl.LookupMethodServiceImpl">
<lookup-method name="creatUser" bean="user" />
</bean>

通过5 的配置 4中的抽象方法 createUser将返回2中bean定义的一个新的实例。
每次通过1 的请求时容器都会创建一个name=“”zsq“”的新实例。

当然spring提供了一种更加简单的方式来处理作用域不一样时属性注入的问题。

即使用@Scope标签的proxyMode属性。比如我要将一个Student注册为作用域为session的bean,并在单实例的loginController中注入。

1 首先建立一个

@Component
@Scope(value="session",proxyMode=ScopedProxyMode.TARGET_CLASS)
//如果Student是一个类,并没有实现任何接口,那么将proxyMode设置为ScopedProxyMode.TARGET_CLASS,将采用CGLIB代理,
//如果Student实现了一个接口,那么可以将proxyMode设置为ScopedProxyMode.INTERFACES,将采用JDK的动态代理,
public class Student {

private String name;

private int age;

//省略setter、getter
}
如果要在xml文件中实现这一步可以在springContext.xml文件中注入

<bean id="student" calss="com.zsq.cn.login.entity.Student" scope="session">
<property name="name">zsq</property>
<property name="age">22</property>
//下面两个二选一
<aop:scoped-proxy />//如果Student是一个类,并没有实现任何接口这样配置将采用CGLIB代
<aop:scoped-proxy proxy-target-class="false" />//如果Student实现了一个接口,这样配置将采用JDK动态代理
</bean>

2 在loginController中注入student
@Autowired
private Student student;

@RequestMapping("/")
public String home(Model model){
model.addAttribute("user", new User());

student.setAge(22);

return "home/index";
}

原文:https://blog.csdn.net/qq_34310242/article/details/78266035

Spring Bean的作用域以及lookup-method标签的使用的更多相关文章

  1. spring bean 的作用域之间有什么区别

    spring bean 的作用域之间有什么区别? spring容器中的bean可以分为五个范围.所有范围的名称都是说明的, 1.singleton:这种bean范围是默认的,这种范围确保不管接受到多个 ...

  2. Spring Bean的作用域(转)

    Spring Bean的作用域 .singleton  [单例] eg:<bean id="personService" class="com.yinger.ser ...

  3. Spring bean的作用域以及生命周期

    一.request与session的区别 request简介 request范围较小一些,只是一个请求. request对象的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请 ...

  4. spring bean 的作用域

    spring bean 的作用域: 1.单例(singleton):默认是单例模式,也就是说不管给定的bean被注入到其他bean多少次,注入的都是同一个实例. 2.原型(prototype):每次注 ...

  5. Spring bean的作用域和生命周期

    bean的作用域 1.singleton,prototype, web环境下:request,session,gloab session 2.通过scope="" 来进行配置 3. ...

  6. [跟我学spring][Bean的作用域]

    Bean的作用域 什么是作用域呢?即“scope”,在面向对象程序设计中一般指对象或变量之间的可见范围.而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围. Sprin ...

  7. Spring Bean的作用域类型

    Bean的作用域类型 singleton :在Spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在; prototype :每次从容器中调用Bean时,都返回一个新的实例,即每 ...

  8. spring bean的作用域和自动装配

    1 Bean的作用域 l  singleton单列:整个容器中只有一个对象实例,每次去访问都是访问同一个对象  默认是单列 l  prototype原型: 每次获取bean都产生一个新的对象,比如Ac ...

  9. Spring Bean Scope (作用域)

    singleton: 单例模式,针对每个spring容器,只有一个该类的实例被管理,每次调用此实例都是同一个对象被返回,所以适用于无状态bean.默认情况下,singleton作为spring容器中b ...

随机推荐

  1. 小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_32..SpringBoot2.x持久化数据方式介绍

    笔记 1.SpringBoot2.x持久化数据方式介绍          简介:介绍近几年常用的访问数据库的方式和优缺点 1.原始java访问数据库             开发流程麻烦        ...

  2. Cannot find module 'laravel-elixir'问题解决方法

    在用gulp 安装elixir的时候报了这样的错误: Laravel elixir npm error Cannot find module 'laravel-elixir/ingredients/c ...

  3. ubuntu上安装jdk

    使用安装包安装:JDK官网下载地址: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.h ...

  4. linux服务之dns

    安装dig工具 [root@cu-app-107 ~]# cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core) [root@cu-ap ...

  5. flutter Card卡片列表组件

    一个 Material Design 卡片.拥有一个圆角和阴影 import 'package:flutter/material.dart'; import './model/post.dart'; ...

  6. Dart函数方法

    /* 内置方法/函数: print(); 自定义方法: 自定义方法的基本格式: 返回类型 方法名称(参数1,参数2,...){ 方法体 return 返回值; } */ void printInfo( ...

  7. 获取IFC构件的位置数据、方向数据

    获取IFC构件的位置数据.方向数据 std::map<int, shared_ptr<BuildingEntity>> map_buildingEntity = b_model ...

  8. Django之Restful API

    理解Restful架构:http://www.ruanyifeng.com/blog/2011/09/restful RESTful设计指南:http://www.ruanyifeng.com/blo ...

  9. 网络编程之Reactor 模式

    基本的架构是 epoll+线程池. 这篇博文主要从以下几个方面进行阐述: (1)reactor模式的一个介绍:(只要是我的理解) (2)关于线程池的说明. (3)如何将epoll + 池结合起来实现一 ...

  10. JS的正则表达式限定开始和结尾等测试

    []:匹配该区间内人任意一个字符^:匹配以某内容开头的$:匹配以模拟内容结尾的字符\w:测试是英文字母,数字,下划线.{}:设置区间,可出现几次到几次该文学习和测试几个正则的方法,测试结果如图,不加多 ...