在默認的狀況下,Spring IoC容器只會對一個Bean建立一個實例,好比下面的測試:java
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig2.class); RoleDataSourceService RoleService = context.getBean(RoleDataSourceService.class); RoleDataSourceService RoleService2 = context.getBean(RoleDataSourceService.class); System.out.println("RoleService == RoleService2:" + (RoleService == RoleService2));
這裏咱們經過類型兩次從Spring IoC容器中取出Bean,而後經過==比較,這是一個位比較。換句話說,就是比較RoleService和RoleService2是否爲同一個對象,通過測試它的結果爲true。
在默認的狀況下,Spring IoC容器只會爲配置的Bean生成一個實例,而不是多個。spring
有時候咱們但願可以經過Spring IoC容器中獲取多個實例,好比Struts2(如今它的使用已經比較少了)中的Action(Struts2的控制層類),它每每綁定了從頁面請求過來的訂單。若是它也是一個實例,那麼訂單就從頭至尾只有一個,而不是多個,這樣就不能知足互聯網的併發要求了。爲了解決這個問題,有時候咱們但願Action是多個實例,每當咱們請求的時候就產生一個獨立的對象,而不是默認的一個,這樣多個實例就能夠在不一樣的線程運行了,就沒有併發問題了。關於這些是由Spring的做用域所決定的。
Spring提供了4種做用域,它會根據狀況來決定是否生成新的對象。
•單例(singleton):它是默認的選項,在整個應用中,Spring只爲其生成一個Bean的實例。
•原型(prototype):當每次注入,或者經過Spring IoC容器獲取Bean時,Spring都會爲它建立一個新的實例。
•會話(session):在Web應用中使用,就是在會話過程當中Spring只建立一個實例。
•請求(request):在Web應用中使用的,就是在一次請求中Spring會建立一個實例,可是不一樣的請求會建立不一樣的實例。
從4種做用域能夠看出,對於Struts2的Action而言,使用請求會合理一些。在4種做用域中會話和請求只能在Web應用中使用sql
代碼清單:給RoleDataSourceServiceImpl聲明原型session
import com.ssm.chapter10.annotation.pojo.Role; import com.ssm.chapter10.annotation.service.RoleDataSourceService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class RoleDataSourceServiceImpl implements RoleDataSourceService { @Autowired @Qualifier("dataSource2") DataSource dataSource = null; // @Override public Role getRole(Long id) { Connection conn = null; ResultSet rs = null; PreparedStatement ps = null; Role role = null; try { conn = dataSource.getConnection(); ps = conn.prepareStatement("select id, role_name, note from t_role where id = ?"); ps.setLong(1, id); rs = ps.executeQuery(); while (rs.next()) { role = new Role(); role.setId(rs.getLong("id")); role.setRoleName(rs.getString("role_name")); role.setNote(rs.getString("note")); } } catch (SQLException e) { e.printStackTrace(); } finally { /**********close database resources************/ try { rs.close(); ps.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } return role; } }
這是再測試兩個對象並不是同一個對象,由於咱們將其聲明爲了原型,每當咱們從Spring IoC容器中獲取對象,它就會生成一個新的實例,這樣兩次獲取就得到了不一樣的對象,因而比較就返回爲false了。併發