# bean scope 属性

## bean scope 属性清单

* singleton 单例（默认）,每个容器内有且jinyou 唯一的实例, 被全局共享
* prototype  多例，每次使用都创建一个实例
* request web 环境下，每一次独立请求存在唯一实例
* session web 环境下，每一个session存在唯一实例
* application web 环境下，ServletContext 存在唯一实例
* websocket 每一次WebSocket 连接中存在唯一实例

其中最常用的就是 singleton 和 prototype

## singleton 和 prototype 举例使用

假设定义一个 UserService 对象， 其内部有一个 UserDao 对象。&#x20;

```java
public class UserDao {
    public UserDao() {
        System.out.println("UserDao 已创建 : "+ this);
    }
}
```

```java
public class UserService {
    private UserDao userDao;

    public UserService() {
        System.out.println("UserService 已创建 : "+ this);
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        System.out.println("调用 setUerDao : "+ userDao);
        this.userDao = userDao;
    }
}

```

如果将 UserDao 的 bean scope 设置为 singleton , 而 UserService 的 bean scope 设置为 prototype， 则多个 的 UserService 会共享一个 UserDao 对象, 存在线程安全问题。

```xml
<!-- 默认 singleton, IoC容器初始化就创建 -->
<bean id="userDao" class="indi.chester.spring.ioc.dao.UserDao"  scope="singleton"/>

<bean id="userService" class="indi.chester.spring.ioc.service.UserService" scope="prototype">
    <property name="userDao"    ref="userDao" />
</bean>
```

如果运行一下就会发现，userDao 对象一共被创建一次

```java
public class SpringApplication {
    public static void main(String[] args) {
        //创建 Spring IoC 容器, 并配置文件在容器中实例化对象
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserDao userDao1 = context.getBean("userDao", UserDao.class);
        UserDao userDao2 = context.getBean("userDao", UserDao.class);
        UserDao userDao3 = context.getBean("userDao", UserDao.class);
    }
}
```

输出结果：

```
UserDao 已创建 : indi.chester.spring.ioc.dao.UserDao@13c78c0b
```

如果将 UserDao 的 bean scope 设置为 prototype , 而 UserService 的 bean scope 设置为 prototype， 则多个 的 UserService 会独享一个 UserDao 对象。

```java
<!-- 若使用 prototype, 则在获取bean时才会创建 -->
<bean id="userDao" class="indi.chester.spring.ioc.dao.UserDao"  scope="prototype"/>

<bean id="userService" class="indi.chester.spring.ioc.service.UserService" scope="prototype">
    <property name="userDao"    ref="userDao" />
</bean>
```

如果运行一下就会发现，userDao 对象一共被创建了三次， 每一个 UserService 对象都独享一个 UserDao 对象。

```java
public class SpringApplication {
    public static void main(String[] args) {
        //创建 Spring IoC 容器, 并配置文件在容器中实例化对象
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserDao userDao1 = context.getBean("userDao", UserDao.class);
        UserDao userDao2 = context.getBean("userDao", UserDao.class);
        UserDao userDao3 = context.getBean("userDao", UserDao.class);
    }
}
```

输出结果：

```
UserDao 已创建 : indi.chester.spring.ioc.dao.UserDao@4cc0edeb
UserDao 已创建 : indi.chester.spring.ioc.dao.UserDao@4667ae56
UserDao 已创建 : indi.chester.spring.ioc.dao.UserDao@77cd7a0
```
