복붙노트

[SPRING] @Scope ( "request")가 작동하지 않습니다.

SPRING

@Scope ( "request")가 작동하지 않습니다.

나는 JSF와 Primefaces (JSF 2.0.2, PrimeFaces 3.0.5, Spring 3.0.0)를 실험하고있다. 그것은 같은 xhtml 페이지에서 관리 빈에 액세스 할 수없는 것 같습니다

<h:inputText  id="lastName" value="#{personalBean.personal_Basic.firstName}"  label="Last Name"  required="true" />

요청은 명령 링크가 Bean 메소드, 서비스에 호출하여 시작하여 페이지를 리턴합니다. 나는 서버 콘솔 Bean에서 볼 수있는 서비스 메소드가 실행된다. 위와 같이 beans 속성을 사용하려고하면 아무 것도 보이지 않습니다. 그러나 사용자의 세션 관리에 사용되는 세션 범위 Bean에 액세스 할 수 있습니다.

죄송합니다.이 질문이 너무 단순하다면. 문제를 해결할 수있는 모든 의견을 크게 주시면 감사하겠습니다.

아래는 제 코드입니다. 이것이 제가 bean을 호출하는 방법입니다 :

<h:form>
    <p:commandLink id="ajax" actionListener="#{personalBean.getPersonalInfo}" style="margin-left:5px;">  
        <h:outputText value="Personal Info" />  <br/>
    </p:commandLink>  
</h:form>

다음은 요청 범위가 지정된 관리 Bean입니다.

package com.test.model;
@ManagedBean
@Scope("request")
public class PersonalBean  implements Serializable {

private static final long serialVersionUID = 199L;
private Personal_Basic personal_Basic;
private IPersonalService personalService;

@Inject
public PersonalBean(final IPersonalService personalService) {
    this.personalService = personalService;
}
public String getPersonalInfo() {
    System.out.println("\n\nPersonalBean#getPersonalInfo called...**");
    User user = null;
    Personal_Basic personal_Basic = personalService.getPersonalBasic();
    this.setPersonal_Basic(personal_Basic);
    System.out.println("personal_Basic data:"+personal_Basic);
    System.out.println("PersonalBean#getPersonalInfo ended...");
    return "/page/personal.html";
}
// Getters/setters for class members followed
}

PersonalService 구현은 @Service로 주석 처리됩니다.

아래는 봄 구성 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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:annotation-config/> 
    <context:component-scan base-package="com.test"/>
...................
...................
</beans>

아래는 faces-config.xml에서 발췌 한 내용입니다.

<?xml version="1.0"?>
<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_0.xsd"
              version="2.0">
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
        <resource-bundle>
            <base-name>Messages</base-name>
            <var>msg</var>
        </resource-bundle>
        <locale-config>
            <default-locale>en</default-locale>
        </locale-config>
  </application>
...........................
</faces-config>

해결법

  1. ==============================

    1. 요소는 기본적으로 @Component, @Repository, @Service 또는 @Controller로 주석 된 모든 bean을 스캔하고 등록합니다.

    요소는 기본적으로 @Component, @Repository, @Service 또는 @Controller로 주석 된 모든 bean을 스캔하고 등록합니다.

    Spring은 또한 javax.annotation.ManagedBean (javax.faces.bean.ManagedBean이 아님)과 JSR-330 표준 주석을 지원하며 이것도 Spring에 의해 스캔되지만 프로젝트에 다음 종속성을 추가해야한다.

    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
    

    Spring Annotation에 대한 모든 해당 주석을 볼 수 있습니다. @Component가 @Named이고 scope가 앞서 언급 한 javax.inject.scope 대신 Springs @Scope annotation을 사용하는 것을 볼 수 있습니다. 따라서 Spring이 애플리케이션의 모든 bean을 관리하기를 원한다면 @Component, @Named 및 javax.annotation.ManagedBean 주석을 사용하여 @Autowired 또는 @Inject를 사용하여 주석을 삽입 할 수 있습니다.

    그리고 javax.faces.bean.ManagedBean으로 주석 처리 된 bean이 초기화 된 것처럼 보이지만 작동하지 않는 이유는 @BalusC에서 언급 한 것처럼 @Inject가 JSF에서 지원되지 않기 때문에 @ManagedProperty 주석을 사용해야합니다.

    Spring과 JSF 모두에서 어떻게 작동하는지에 대한 약간의 배경 지식 :

    실제로 애플리케이션이 시작될 때 JSF와 Spring을 사용하는 두 개의 IOC 컨테이너가 애플리케이션에 있습니다. 먼저 faces-config.xml에 구성된 org.springframework.web.jsf.el.SpringBeanFacesELResolver가 스프링 루트 WebApplicationContext에 위임하여 스프링 정의 Bean에 대한 이름 참조를 먼저 확인한 다음 기본 JSF 구현의 기본 해결 자로 해석합니다.

    이제 JSF 빈을 처음봤을 때 생성 된 다음 setter 메소드를 통해 관리되는 속성이 설정되므로 @ManagedProperty 주석을 사용하여 Spring 빈을 삽입 할 수있다.

    package com.test.model;
    @ManagedBean
    @RequestScoped
    public class PersonalBean  implements Serializable {
    @ManagedProperty(value="#{personalService}")
    private IPersonalService personalService;
    public IPersonalService getPersonalService() {
        return personalService;
    }
    
    public void setPersonalService(IPersonalService personalService) {
        this.personalService= personalService;
    }
    

    또는 Spring Bean을 수동으로 가져올 수도 있습니다.

    org.springframework.web.context.support.WebApplicationContextUtils는 다음과 같습니다 :

    private Object getSpringBean(String name){
            WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(
                    (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext());
            return ctx.getBean(name);
    }
    

    다음과 같이 사용하십시오.

    Personal_Basic personal_Basic = ((IPersonalService) getSpringBean("personalService")).getPersonalBasic();
    

    하지만 응용 프로그램에서 두 개의 컨테이너를 사용하는 대신 Spring 컨테이너를 사용하여 JSF 빈에 @Component 주석을 추가하여 모든 bean을 관리 할 수 ​​있으며 Spring 애노테이션을 사용할 수 있다는 것을 알고 있고 완벽하게 사용해야 함을 의미하지는 않습니다.

    참조 :

  2. ==============================

    2.@ManagedBean과 스프링 범위를 혼용 할 수는 없으므로 @ManagedBean과 @RequestScope 또는 @Componenet과 @Scope ( "session") 중에서 선택해야합니다.

    @ManagedBean과 스프링 범위를 혼용 할 수는 없으므로 @ManagedBean과 @RequestScope 또는 @Componenet과 @Scope ( "session") 중에서 선택해야합니다.

  3. from https://stackoverflow.com/questions/12470512/scoperequest-not-working by cc-by-sa and MIT license