Javax.enterprise.context.SessionsScoped在SpringContainer中表现得像Singleton,JSF作为前端

时间:2013-03-06 14:17:42

标签: java spring jsf-2

我的Web应用程序有前端JSF / RichFaces,中间层Spring和Hibernate for DB。当我部署应用程序并从我的系统和我的朋友访问时访问时,我的朋友可以继续我所做的任何操作(对象表现为singleton / applicationcontext)。下面是我的会话类的代码,web.xml,faces-config.xml和spring.xml。我想由于同样的原因,我认为viewcoped bean也不符合我的期望。在这种情况下,有人可以提供帮助。

package org.kp.business;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class OliHolder implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Map<String, ArrayList<OliData>> oliTypesHolder = new HashMap<String, ArrayList<OliData>>();


    public void addOli(String oliType) {
        OliData oliDetails = new OliData();
        oliDetails.setOliName(oliType);
        oliDetails.initData(oliType);
        ArrayList<OliData> tempHolder = null;
        if(!oliTypesHolder.containsKey(oliType))
        {
            tempHolder = new ArrayList<OliData>();
            tempHolder.add(oliDetails);
            oliTypesHolder.put(oliType, tempHolder);
        }else{
            tempHolder = oliTypesHolder.get(oliType);
            tempHolder.add(oliDetails);
        }
    }

    public void deleOli(int num, String oliType) {
        ArrayList<OliData> list = oliTypesHolder.get(oliType);
        if(null != list && list.size() > 0){
            if((list.size()>num)){  
                list.remove(num);
            }
        }
    }

    public void resetOliHolder(){
        oliTypesHolder.clear();
    }

    public List<OliData> getOlisByType(String oliType){
        ArrayList<OliData> tempHolder = oliTypesHolder.get(oliType);
        return tempHolder;
    }

    public void resetCurrentType(String selectedOli) {
         oliTypesHolder.remove(selectedOli);
    }

    public Map<String, ArrayList<OliData>> getOliTypesHolder() {
        return oliTypesHolder;
    }

}

脸部-config.xml中

<?xml version="1.0" encoding="UTF-8"?>

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"
    version="2.1">

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>

</faces-config>

的web.xml

<?xml version="1.0"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>EBMMaker</display-name>
    <!-- <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
    <context-param>
        <param-name>org.richfaces.skin</param-name>
        <param-value>ruby</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/SpringConfig.xml</param-value>
    </context-param>
    <listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
</web-app>

Spring.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"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

        <context:annotation-config />
        <context:component-scan base-package="org.kp"></context:component-scan>

        <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/ebm" />
            <property name="username" value="root" />
            <property name="password" value="root" />
        </bean>
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="packagesToScan" value="örg.kp.db.model" />
            <property name="configLocation">
                <value>
                    classpath:/org/kp/db/hibernate.cfg.xml
                </value>
            </property>
        </bean>

</beans>

这是一个类,我正在尝试访问用于从数据库获取数据的bbOli Bean因为我正在手动创建对象,所以我正在使用应用程序上下文访问bbOli Bean。我不确定OLIData对象的范围。

package org.kp.business;

import java.util.ArrayList;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

import org.kp.db.model.TblEBMFieldDetails;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class OliData {

    BusinessOli bbOli;

    private String oliName;

    public OliData() {
        ApplicationContext ctx = WebApplicationContextUtils
                .getRequiredWebApplicationContext((ServletContext) FacesContext
                        .getCurrentInstance().getExternalContext().getContext());
        bbOli = (BusinessOli) ctx.getBean("bbOli");
    }

    private String commentText;


    public String getCommentText() {
        return commentText;
    }

    public void setCommentText(String commentText) {
        this.commentText = commentText;
    }

    public String getOliName() {
        return oliName;
    }

    public void setOliName(String oliName) {
        this.oliName = oliName;
    }

    private List<TblEBMFieldDetails> dbEBMData;
    private List<EBMDataForView> renderEBMData;

    public List<EBMDataForView> getRenderEBMData() {
        return renderEBMData;
    }

    public void setRenderEBMData(List<EBMDataForView> renderEBMData) {
        this.renderEBMData = renderEBMData;
    }

    public List<TblEBMFieldDetails> getDbEBMData() {
        return dbEBMData;
    }

    public void setDbEBMData(List<TblEBMFieldDetails> dbEBMData) {
        this.dbEBMData = dbEBMData;
    }

    public void initData(String oliName) {
        this.dbEBMData = bbOli.getOliTypeSpfcData(oliName);
        renderEBMData = new ArrayList<EBMDataForView>();
        for (TblEBMFieldDetails dt : dbEBMData) {
            EBMDataForView data = new EBMDataForView();
            data.setCmplxFlg(dt.isCollectionFlg());
            if (dt.isCollectionFlg() && null != dt.getValues()) {
                data.setFieldCollectionValue(dt.getValues().split(","));
                System.out.println("Hey I'm: "+data.getFieldCollectionValue().length);
            }

            data.setFieldDefaultValue(dt.getDefaultValue());
            data.setFieldName(dt.getFieldName());
            data.setRequiredFld(dt.isReqFlg());
            renderEBMData.add(data);
        }
    }

}

变更后

import org.springframework.beans.factory.annotation.Autowired;

@ManagedBean(name = "bbOliHolder")
@ViewScoped
public class OliHolderBacking implements Serializable{


    private static final long serialVersionUID = 1L;

    private String selectedTab;

    @Autowired
    BusinessOli bbOli;

    public BusinessOli getBbOli() {
        return bbOli;
    }


    public void setBbOli(BusinessOli bbOli) {
        this.bbOli = bbOli;
    }

    @Autowired
    OliHolder oliHolder;

    private String[] allOliTypes = null;


    @PostConstruct
    public void init() {

        allOliTypes = getBbOli().getAllOlisFromDB();
        olis = new ArrayList<OliData>();
    }

}

服务层Bean

import java.util.List;

import org.kp.db.dao.EBMDetailDao;
import org.kp.db.dao.impl.OlisImpl;
import org.kp.db.model.TblEBMFieldDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

@Service("bbOli")
@Scope("prototype")
public class BusinessOli{

    @Autowired
    OlisImpl olisImpl;

    @Autowired
    EBMDetailDao ebmData;

    public String[] getAllOlisFromDB() {

        String[] str = olisImpl.getAllOlis();
        return str;
    }
}

然而,BusinessOli中的自动装配在更改之前就已经开始工作了

2 个答案:

答案 0 :(得分:1)

据我所知,Spring并不支持Java EE 6(JSR 299)中引入的CDI注释,因此您应该使用spring注释来定义bean的范围,在您的情况下将是:

import org.springframework.context.annotation.Scope;

@Scope("session")

在你的情况下,Spring使用默认范围,这确实是Singleton。

答案 1 :(得分:0)

如果你一起使用Spring和JSF,那么使用Spring bean而不是JSF Managed bean是有益的。 Spring bean几乎提供了JSF托管bean的所有功能,除此之外还增加了许多有用的Spring功能(AOP,代理,编织,MessageSources等)。

如果您决定使用Spring bean,则必须使用WebApplicationContext中列出的Spring Scope:

import org.springframework.context.annotation.Scope;
import org.springframework.web.context.WebApplicationContext

@Scope(WebApplicationContext.SCOPE_SESSION)

查看范围

有一个问题。如您所见,SCOPE_VIEW中没有WebApplicationContext。 Spring中尚不支持JSF 2 View范围。 现在,您必须提供自己的视图范围实现。这并不难: