Spring當(dāng)中aop:scoped-proxy 的用法

馬克- to-win:馬克 java社區(qū):防盜版實(shí)名手機(jī)尾號(hào): 73203
當(dāng)把生命周期短的bean(比如下例中的MyBean)注入到生命周期長的bean(比如下例中的SingletonBean)時(shí),我們必須做特殊處理,比如加<aop:scoped-proxy>來修飾短生命周期的bean。為什么?其實(shí)也好理解。比如下例中的生命周期長的bean (SingletonBean)的類型是Singleton,還沒有用戶訪問時(shí),在最初的時(shí)刻就建立了,而且只建立一次。這時(shí)它的一個(gè)屬性myBean卻要急著指向另外一個(gè)session類型的bean(com.MyBean),而com.MyBean的生命周期短(只有當(dāng)有用戶訪問時(shí),它才被生成)?,F(xiàn)在處于初始階段,還沒有用戶上網(wǎng)呢,所以com.MyBean的真正對(duì)象還沒有生成呢。所以<aop:scoped-proxy>的意思就是讓myBean這個(gè)屬性指向com.MyBean的一個(gè)代理對(duì)象。(該代理對(duì)象擁有和com.MyBean完全相同的public接口。調(diào)用代理對(duì)象方法時(shí),代理對(duì)象會(huì)從Session范圍內(nèi)獲取真正的com.MyBean對(duì)象,調(diào)用其方法)。下例中如果去除<aop:scoped-proxy /> 會(huì)報(bào)以下的錯(cuò)誤:Error creating bean with name 'myBean': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean,注意在做以下實(shí)驗(yàn)時(shí),要導(dǎo)入包c(diǎn)glib-nodep-2.1_3.jar。


例 2.4.1

    <bean id="myBean" class="com.MyBean" scope="session">
         <aop:scoped-proxy />
    </bean>  
  
    <bean id="singletonBean" class="com.SingletonBean">
        <property name="myBean">
            <ref bean="myBean" />
        </property>
    </bean>





package com;
public class MyBean implements IMyBean{
    private int count;
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public void increment()
    {
        count ++;
    }
}



package com;
public interface IMyBean {
    public void increment();
    public int getCount();
}



package com;
public class SingletonBean {
    private MyBean myBean;
    public int getCount() {
        return myBean.getCount();
    }
    public void increment() {
        myBean.increment();
    }
    public void setMyBean(MyBean myBean) {
        this.myBean = myBean;
    }
}





package com;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;
import service.interfac.ILoginService;

@Controller
public class HelloWorldController {
    private ILoginService loginServic;

    private IMyBean myBean;
    @RequestMapping("/helloa")
    public ModelAndView helloWorld(HttpServletRequest request, HttpServletResponse response,
            HttpSession sesssion) {
        ServletContext sc=RequestContextUtils.getWebApplicationContext(request).getServletContext();
        WebApplicationContext wac=WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
        ILoginService loginServic=(ILoginService)wac.getBean("loginService");
        SingletonBean singletonBean=(SingletonBean)wac.getBean("singletonBean");
 //       loginServic.login();
        singletonBean.increment();
        System.out.println("myBean.getCount() "+singletonBean.getCount());
        System.out.println("after loginServic.login()");
        return new ModelAndView("/helloq", "message", "你好");
    }
}


輸出結(jié)果:(在同一個(gè)瀏覽器中反復(fù)執(zhí)行就是以下結(jié)果,換一個(gè)瀏覽器數(shù)據(jù)重新向上加)

myBean.getCount() 1
after loginServic.login()
myBean.getCount() 2
after loginServic.login()
myBean.getCount() 3
after loginServic.login()