2015-02-21 17:47

[轉載] [JSP] Expression Language (EL)

轉載自:JSP 表达式语言 | w3cschool菜鸟教程

JSP 表達式語言(EL)使得訪問存儲在 JavaBean 中的數據變得非常簡單。JSP EL 既可以用來創建算術表達式也可以用來創建邏輯表達式。在 JSP EL 表達式內可以使用整型數,浮點數,字符串,常量 true、false,還有 null。


一個簡單的語法


典型的,當您需要在JSP標簽中指定一個屬性值時,只需要簡單地使用字符串即可:
<jsp:setProperty name="box" property="perimeter" value="100"/>

JSP EL 允許您指定一個表達式來表示屬性值。一個簡單的表達式語法如下:
${expr}

其中,expr 指的是表達式。在 JSP EL 中通用的操作符是"."和"[]"。這兩個操作符允許您通過內嵌的 JSP 物件訪問各種各樣的 JavaBean 屬性。

舉例來說,上面的 <jsp:setProperty> 標簽可以使用表達式語言改寫成如下形式:
<jsp:setProperty name="box" property="perimeter" 
                  value="${2*box.width+2*box.height}"/>

當 JSP 編譯器在屬性中見到"${}"格式後,它會產生代碼來計算這個表達式,並且產生一個替代品來代替表達式的值。

您也可以在標簽的模板文本中使用表達式語言。
比如 <jsp:text> 標簽簡單地將其主體中的文本插入到 JSP 輸出中:
<jsp:text>
  <h1>Hello JSP!</h1>
</jsp:text>

現在,在 <jsp:text> 標簽主體中使用表達式,就像這樣:
<jsp:text>
  Box Perimeter is: ${2*box.width + 2*box.height}
</jsp:text>

在 EL 表達式中可以使用圓括號來組織子表達式。
比如 ${(1 + 2) * 3} 等於9,但是 ${1 + (2 * 3)} 等於7。

想要停用對 EL 表達式的評估的話,需要使用 page 指令將 isELIgnored 屬性值設為 true:
<%@ page isELIgnored ="true|false" %>

這樣,EL 表達式就會被忽略。若設為 false,則容器將會計算 EL 表達式。



EL 中的基礎操作符


EL表達式支持大部分Java所提供的算術和邏輯操作符:
操作符描述
.訪問一個 Bean 屬性或者一個映射條目
[]訪問一個數組或者鏈表的元素
()組織一個子表達式以改變優先級
+
-減或負
*
/ 或 div
% 或 mod取模
== 或 eq測試是否相等
!= 或 ne測試是否不等
< 或 lt測試是否小於
> 或 gt測試是否大於
<= 或 le測試是否小於等於
>= 或 gt測試是否大於等於
&& 或 and測試邏輯與
|| 或 or測試邏輯或
! 或 not測試取反
empty測試是否空值



JSP EL 中的函數


JSP EL 允許您在表達式中使用函數。這些函數必須被定義在自定義標簽庫中。函數的使用語法如下:
${ns:func(param1, param2, ...)}

ns 指的是命名空間(namespace),func 指的是函數的名稱,param1 指的是第一個參數,param2 指的是第二個參數,以此類推。比如,有函數 fn:length,在 JSTL 庫中定義,可以像下面這樣來獲取一個字符串的長度:
${fn:length("Get my length")}

要使用任何標簽庫中的函數,您需要將這些庫安裝在服務器中,然後使用 <taglib> 標簽在JSP文件中包含這些庫。



JSP EL 隱含物件


JSP EL支持下表列出的隱含物件:
隱含物件描述
pageScopepage 作用域
requestScoperequest 作用域
sessionScopesession 作用域
applicationScopeapplication 作用域
paramRequest 物件的參數,字符串
paramValuesRequest 物件的參數,字符串集合
headerHTTP 信息頭,字符串
headerValuesHTTP 信息頭,字符串集合
initParam上下文初始化參數
cookieCookie 值
pageContext當前頁面的 pageContext

您可以在表達式中使用這些物件,就像使用變量一樣。接下來會給出幾個例子來更好的理解這個概念。



pageContext 物件


pageContext 物件是 JSP 中 pageContext 物件的引用。通過 pageContext 物件,您可以訪問 request 物件。比如,訪問 request 物件傳入的查詢字符串,就像這樣:
${pageContext.request.queryString}



Scope 物件


pageScope,requestScope,sessionScope,applicationScope 變量用來訪問存儲在各個作用域層次的變量。

舉例來說,如果您需要顯式訪問在 applicationScope 層的 box 變量,可以這樣來訪問:
${applicationScope.box}



param 和 paramValues 物件


param 和 paramValues 物件用來訪問參數值,通過使用 request.getParameter 方法和 request.getParameterValues 方法。

舉例來說,訪問一個名為 order 的參數,可以這樣使用表達式:${param.order} 或者 ${param["order"]}

接下來的例子表明了如何訪問request中的username參數:
<%@ page import="java.io.*,java.util.*" %>
<%
    String title = "Accessing Request Param";
%>
<html>
  <head>
    <title><% out.print(title); %></title>
  </head>
  <body>
    <center>
      <h1><% out.print(title); %></h1>
    </center>
    <div align="center">
      <p>${param["username"]}</p>
    </div>
  </body>
</html>

param 物件返回單一的字符串,而 paramValues 物件則返回一個字符串數組。



header 和 headerValues 物件


header 和 headerValues 物件用來訪問信息頭,通過使用 request.getHeader 方法和 request.getHeaders 方法。

舉例來說,要訪問一個名為 user-agent 的信息頭,可以這樣使用表達式:${header.user-agent} 或者 ${header["user-agent"]}

接下來的例子表明了如何訪問 user-agent 信息頭:
<%@ page import="java.io.*,java.util.*" %>
<%
    String title = "User Agent Example";
%>
<html>
  <head>
    <title><% out.print(title); %></title>
  </head>
  <body>
    <center>
      <h1><% out.print(title); %></h1>
    </center>
    <div align="center">
      <p>${header["user-agent"]}</p>
    </div>
  </body>
</html>

運行結果如下:
User Agent Example
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; HPNTDF; .NET4.0C; InfoPath.2)

header 物件返回單一值,而 headerValues 則返回一個字符串數組。
2015-02-21 11:23

[轉載] [Java] BigDecimal的四則運算

轉載自:[Java] BigDecimal的四則運算

最近因為需要計算報表中的房物出租率,會用到BigDecimal的運算,目前只知道int, double, float等基本型態的我,連BigDecimal是三小都不太清楚,後來查了許多資料才知道原來BigDecimal可以用在精確的數學計算上面,許多商業用報表都需要用到BigDecimal型別。

BigDecimal有兩個較常用到的方法:
  1. BigDecimal(double val)
    Translates a double into a BigDecimal.
  2. BigDecimal(String val)
    Translates the String repre sentation of a BigDecimal into a BigDecimal.

API將上述方法解釋的非常清楚,而我們如果要精確計算,一定得把數值轉型成String型別,否則得到的結果會是有問題的。簡單來說,若要使用BigDecimal做加法計算必須有以下步驟:
  1. 需要先將兩個浮點數(double)轉為String,並分別宣告為BigDecimal
  2. 在其中一個浮點數使用add方法,傳入另一個浮點數作為參數
  3. 作為運算結果的參數(答案)也須宣告為BigDecimal
  4. 最後把運算的結果(BigDecimal)再轉換為浮點數

在BigDecimal的運算中,加為add, 減為sub,乘為multiply,除法為divide。在做運算之前需針對每一個變數new BigDecimal物件,舉例如下:
// 精確的加法運算,v1 為加數,v2 為被加數,return v1 + v2
public static double add(double v1,double v2){
    BigDecimal b1 = new BigDecimal(Double.toString(v1));
    BigDecimal b2 = new BigDecimal(Double.toString(v2));
    return b1.add(b2).doubleValue();
}

在運算之後若需四捨五入該怎麼辦呢?舉例如下:
// v 為需要四捨五入的數字,scale 為小數點後面要保留幾位數,return 四捨五入後的結果
public static double round(double v,int scale){
    if(scale < 0){
        throw new IllegalArgumentException(
            "The scale must be a positive integer or zero"
        );
    }
    BigDecimal b = new BigDecimal(Double.toString(v));
    BigDecimal one = new BigDecimal("1");
    return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}

完整範例請參考以下文字:
import java.math.BigDecimal;
public class Testtest {

    public static void main(String[]args){
 
        // 宣告第一個需要運算的數值
        BigDecimal bigNumber = new BigDecimal("89.1234567890123456789"); 
  
        // 宣告第二個需要運算的數值
        BigDecimal bigRate = new BigDecimal(1000); 
  
        // 宣告運算後的答案為 bigResult
        BigDecimal bigResult = new BigDecimal(0);
  
        // bigResult 為 bigNumBer * bigRate
        bigResult = bigNumber.multiply(bigRate); 
  
        // 印出 bigResult
        System.out.println(bigResult.toString()); 
  
        // 將 bigNumber 四捨五入變為 double 型態
        double dData = bigNumber.doubleValue(); 
  
        // 印出 dDate
        System.out.println(dData);
  
        // 宣告 data2 為 bigNumber/bigRate 並四捨五入至小數點第二位
        double data2 = bigNumber
                           .divide(bigRate,2,BigDecimal.ROUND_HALF_UP)
                           .doubleValue();
  
        // 印出 data2
        System.out.println(data2);
    }
}

2015-02-21 11:03

[Java] System Property 筆記

String version = System.getProperty("java.version");

java.versionJava 執行期環境版本
java.vendorJava 執行期環境供應商
java.vendor.urlJava 供應商的 URL
java.homeJava 安裝目錄
java.vm.specification.versionJava 虛擬機規範版本
java.vm.specification.vendorJava 虛擬機規範供應商
java.vm.specification.nameJava 虛擬機規範名稱
java.vm.versionJava 虛擬機實現版本
java.vm.vendorJava 虛擬機實現供應商
java.vm.nameJava 虛擬機實現名稱
java.specification.versionJava 執行期環境規範版本
java.specification.vendorJava 執行期環境規範供應商
java.specification.nameJava 執行期環境規範名稱
java.class.versionJava 類別格式版本號
java.class.pathJava 類別路徑
java.library.path加載庫時搜索的路徑串列(linked-list)
java.io.tmpdir預設的暫時檔路徑
java.compiler要使用的 JIT 編譯器的名稱
java.ext.dirs一個或多個擴展目錄的路徑
os.name作業系統 的名稱
os.arch作業系統 的架構
os.version作業系統 的版本
file.separator檔分隔設定(在 UNIX 系統中是“/”)
path.separator路徑分隔設定(在 UNIX 系統中是“:”)
line.separator行分隔設定(在 UNIX 系統中是“/n”)
user.name用戶的賬戶名稱
user.home用戶的主目錄
user.dir用戶的當前工作目錄


List all system properties
Properties props = System.getProperties();
props.list(System.out);
2015-02-21 10:55

[Java] ServletRequest 筆記

Request URL
http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S%3F+ID?p+1=c+d&p+2=e+f#a

MethodURL DecodedResult
getContextPath()/app
getLocalAddr()127.0.0.1
getLocalName()30thh.loc
getLocalPort()8480
getMethod()GET
getPathInfo()yes/a?+b
getProtocol()HTTP/1.1
getQueryString()nop+1=c+d&p+2=e+f
getRequestedSessionId()noS%3F+ID
getRequestURI()no/app/test%3F/a%3F+b;jsessionid=S+ID
getRequestURL()nohttp://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S+ID
getScheme()http
getServerName()30thh.loc
getServerPort()8480
getServletPath()yes/test?
getParameterNames()yes[p 2, p 1]
getParameter("p 1")yesc d

2015-02-14 15:18

VMware Authorization Service 無法啟動

在 VMware 啟動虛擬機時發生了 Service "VMware Authorization Service" did not start. 的錯誤訊息,原因是相依的 vmx86 服務遺失了,可以透過以下指令重建服務:

sc create vmx86 type= kernel start= auto binpath= "C:\Program Files (x86)\VMware\VMware Workstation\vmx86.sys" displayname= "VMware Virtualization Driver"
2015-02-10 15:52

JAX-WS RI + Spring 4 自動 Exporting Service

Spring 4 的部分我就不多說了,請自行配置 jar 檔,這裡我用 jaxws-ri-2.2.10.zipjaxws-spring-1.9.jar 進行配置。


AccountService.java
package test.jaxws.webservice;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public interface AccountService {

    @WebMethod
    void insertAccount(String acc);

    @WebMethod
    String[] getAccounts(String role);
}
先來定義一個 interface,這主要是給 Client 用的。


AccountServiceImpl.java
package test.jaxws.webservice;

import javax.jws.WebMethod;
import javax.jws.WebService;
import org.springframework.stereotype.Component;

@Component
@WebService(serviceName="AccountService")
public class AccountServiceImpl implements AccountService {

    @Override
    @WebMethod
    public void insertAccount(String acc) {
    }

    @Override
    @WebMethod
    public String[] getAccounts(String role) {
        return new String[] {"tom", "jax"};
    }
}
接者是 Web Service 的主體,@Component 是為了讓 Spring component-scan 自動建立 Bean,@WebService 則是用定義要 Exporting 到 JAX-WS 的 serviceName,由於是透過 Spring 去管理 bean 所以可以用 @Autowired 引用其他資源。


JaxWsRtServletServiceExporter.java
package test.jaxws.webservice;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.jws.WebService;
import javax.xml.ws.WebServiceProvider;

import org.jvnet.jax_ws_commons.spring.SpringService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.CannotLoadBeanClassException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import com.sun.xml.ws.transport.http.servlet.SpringBinding;

public class JaxWsRtServletServiceExporter implements BeanFactoryAware, InitializingBean {

    private ListableBeanFactory beanFactory;
    private String basePath;

    public void setBasePath(String basePath) {
        this.basePath = basePath;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        if (!(beanFactory instanceof ListableBeanFactory)) {
            throw new IllegalStateException(getClass().getSimpleName() + " requires a ListableBeanFactory");
        }
        this.beanFactory = (ListableBeanFactory) beanFactory;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (this.beanFactory instanceof SingletonBeanRegistry == false) { return; }

        SpringService service = new SpringService();

        Set<String> beanNames = new LinkedHashSet<String>(this.beanFactory.getBeanDefinitionCount());
        beanNames.addAll(Arrays.asList(this.beanFactory.getBeanDefinitionNames()));

        if (this.beanFactory instanceof ConfigurableBeanFactory) {
            beanNames.addAll(Arrays.asList(((ConfigurableBeanFactory) this.beanFactory).getSingletonNames()));
        }

        SingletonBeanRegistry factory = (SingletonBeanRegistry)this.beanFactory;

        for (String beanName : beanNames) {
            try {
                Class<?> type = this.beanFactory.getType(beanName);
                if (type == null || type.isInterface()) { continue; }

                WebService wsAnnotation = type.getAnnotation(WebService.class);
                WebServiceProvider wsProviderAnnotation = type.getAnnotation(WebServiceProvider.class);
                if (wsAnnotation == null && wsProviderAnnotation == null) { continue; }


                String serviceName;
                if (wsAnnotation != null) {
                    serviceName = wsAnnotation.serviceName();
                } else {
                    serviceName = wsProviderAnnotation.serviceName();
                }

                service.setImpl(type);
                service.setBean(this.beanFactory.getBean(beanName));

                SpringBinding springBinding = new SpringBinding();
                springBinding.setBeanName(serviceName + "Binding");
                springBinding.setUrl(this.basePath + "/" + serviceName);
                springBinding.setService(service.getObject());

                factory.registerSingleton(serviceName + "Binding", springBinding);
            }
            catch (CannotLoadBeanClassException ex) {
                // ignore beans where the class is not resolvable
            }
        }
    }
}
為了可以自動 Exporting Service 到 JaxWs RI Servlet 需要建立一個 Exporter,這裡將具有 @WebService 或 @WebServiceProvider 的 Bean 包裝成 SpringBinding 再註冊到 Spring BeanFactory 裡,這樣 WSSpringServlet 就會取到這邊註冊 SpringBinding Bean 進行 Exporting。


web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
 version="3.0"
>
 <display-name>test-jaxws-rt</display-name>

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/jaxws.xml</param-value>
 </context-param>

 <context-param>
     <param-name>webAppRootKey</param-name>
     <param-value>test-jaxws-rt.root</param-value>
   </context-param> 
 
 <servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/dispatcher.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>

    <servlet>
        <servlet-name>jaxws-servlet</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jaxws-servlet</servlet-name>
        <url-pattern>/service/*</url-pattern>
    </servlet-mapping>
</web-app>
在 web.xml 同時註冊兩個 servlet,分別是 Spring MVC 的 DispatcherServlet 跟 JAX-WS 的 WSSpringServlet,這邊主要是透過 ContextLoaderListener 去啟用全域的 ApplicationContext 去管理所有的 Bean。


jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd"
>
    <context:component-scan base-package="test.jaxws.webservice" />

    <bean id="jaxWsRtServletServiceExporter" class="test.jaxws.webservice.JaxWsRtServletServiceExporter">
        <property name="basePath" value="/service"/>
    </bean>
</beans>
jaxws.xml 是給 ContextLoaderListener 的設定,這裡用 component-scan 去找出 test.jaxws.webservice 下有 @Component 的 Bean,以及用 JaxWsRtServletServiceExporter 去轉換所有的 @WebService 到 SpringBinding。


dispatcher.xml
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd"
>
    <context:component-scan base-package="test.jaxws.controller" />

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="accountWebService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean" scope="request">
        <property name="serviceInterface" value="test.jaxws.webservice.AccountService"/>
        <property name="wsdlDocumentUrl" value="http://localhost:8090/test-jaxws-rt/service/AccountService?wsdl"/>
        <property name="namespaceUri" value="http://webservice.jaxws.test/"/>
        <property name="serviceName" value="AccountService"/>
        <property name="portName" value="AccountServiceImplPort"/>
    </bean>
</beans>
在這裡用 JaxWsPortProxyFactoryBean 去建立 WebService Client,因為是同一個 Web Content 所以用 scope="request" 延遲建立。


HomeController.java
package test.jaxws.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.ModelAndView;

import test.jaxws.webservice.AccountService;

@Controller
public class HomeController {

    @Autowired
    private WebApplicationContext appContent;

    @RequestMapping("/")
    public ModelAndView index() {
        AccountService service = appContent.getBean("accountWebService", AccountService.class);
        String[] users = service.getAccounts("user");

        ModelAndView model = new ModelAndView("index");
        model.addObject("users", users);

        return model;
    }
}
接下來就是連接的 Client,這邊用 WebApplicationContext 延遲取得 AccountService,在 http://localhost:8080/test-jaxws-rt/service/AccountService 就可以看到 service 的主頁面。


參考資料:
JAX-WS + Spring integration example
22. Remoting and web services using Spring
2015-02-06 13:01

[轉載] spring 的配置文件中 mvc:view-controller path 使用方法

1、重定向
<mvc:view-controller path="/" view-name="redirect:/admin/index"/>
即如果当前路径是 / 则重定向到 /admin/index


2、view name
<mvc:view-controller path="/" view-name=admin/index"/>
如果当前路径是 / 则交给相应的视图解析器直接解析为视图


<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="2">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="contentType" value="text/html"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>
则得到的视图时 /WEB-INF/jsp/admin/index.jsp


不想进 controller,可以在 spring-mvc.xml 中配置静态访问路径
<!-- 访问静态资源文件  -->
<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>

像这样,jsp 文件若放在静态路径 /images 下,可以直接访问,而不经过 controller。
2015-02-06 12:48

[轉載] Spring Bean Scope

轉載自:Spring Bean Scope 學習

在 Spring 中定義一個 Bean 時,可以針對其 scope 加以設定。在新版的 Spring 中,共有五種不同的 scope 可以設定,分別為:
singleton
在 Spring IoC Container,該 bean 只會有單一實例(a single instance),此為 Spring 預設值
prototype
在 Spring IoC Container 中,該 bean 可以有多個實例(any number of object instances)
request
在每一次的 HTTP Request,spring container 會根據 loginAction bean 的定義來建立一個全新的 instance,而且僅在目前的 request 中有效,所以可以放心的去更改 instance 的內部狀態,請求結束,request scope 的 bean instance 會被 destroy
session
針對某個 HTTP Session,spring container 會根據 userPreference bean 的定義來建立一個全新的 instance,同樣的,和 request scope 一樣,可以放心的去更改 instance 內部狀態。
global-session
僅在 portlet 為基礎的 Web 應用下有作用。Porlet 的規範中定義了 global session 的概念。


在定義 scope 時,會在 bean 中定義如下:
<bean id="helloWorld" class="HelloWorld" scope="singleton">

當 scope 設定為 singleton 時,整個 container 只會有一個 instance,所以下方的 obj 和 obj1 都會是同一個 instance。
ApplicationContext context = new ClassPathXmlApplicationContext("Bean.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.setMessage("hello");
obj.getMessage();
HelloWorld obj1 = (HelloWorld) context.getBean("helloWorld");
obj1.getMessage();


<bean id="helloWorld" class="HelloWorld" scope="prototype">

如果設定為 prototype 時,obj 和 obj1 將會是不同的 instances,可以分別進行操作。在這裡,singleton 的單一 instance 是用 id 來進行識別,不同 id、相同 class 時,還是可以有多個 instances(getBean傳入不同的id即可)。


request、session 和 global-session 三種 scope 只能在 web 環境中使用,如果在非 web 環境設定,會出現【No Scope registered for scope 'request'】的錯誤。