spring Bean的作用域


  在默認的情況下,Spring IoC容器只會對一個Bean創建一個實例,比如下面的測試:

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 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應用中使用

  代碼清單:給RoleDataSourceServiceImpl聲明原型

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了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM