bestsource

스프링 세션 범위 콩(컨트롤러) 및 서비스에 대한 언급, 직렬화 측면

bestsource 2023. 9. 6. 22:11
반응형

스프링 세션 범위 콩(컨트롤러) 및 서비스에 대한 언급, 직렬화 측면

  • 케이스 - - 가 ( )@Controller)와 함께@Scope("session").
  • 세션에 투입되는 수업들은 보통 실행될 것으로 예상됩니다.Serializable예를 들어, 서버가 재시작될 경우 물리적으로 저장할 수 있도록 하기 위해.
  • 가 하는 를 구현하는 Serializable 모든 봄 콩)이라는 것을 , 은 하고 합니다 이라는 될 을 이 합니다 을 이라는 될 이들은 종종 트랜잭션 관리자, 엔티티 관리자 공장 등을 지칭하는 프록시입니다.
  • 가 과 를 하고 은 은 하고 를 가 ApplicationContext하여, ApplicationContextAware할 수 즉, 는 가 을 할 할 을 는 가 .그리고 아이디어로 직렬화할 수 없는 많은 연결을 보유하고 있기 때문에 부패한 상태로 복원될 것입니다.

지금까지 저는 대부분 이 문제들을 무시해 왔습니다.에 저는 저의 봄 했습니다.는의봄을다할을든다을할ly에fgdytis을 .transientreadResolve() 클래스에 WebApplicationContextUtils/ServletContext에 하는 경우ThreadLocal. 이것은 지루하지만 개체가 역직렬화될 때 개체의 종속성이 현재 응용프로그램 컨텍스트와 "최신"됨을 보장합니다.

이에 대한 허용된 관행이나 스프링 컨텍스트의 일부를 직렬화하기 위한 지침이 있습니까?

JSF에서 관리되는 빈(~컨트롤러)은 작업 기반 웹 프레임워크와 달리 상태 저장됩니다.그래서 아마도 제 질문은 스프링-mvc 보다는 JSF를 의미합니다.

프레젠테이션(약 1:14)에서 화자는 현재 애플리케이션 컨텍스트(deserialization)에서 인스턴스를 얻는 직렬화 불가능한 콩의 프록시를 제공함으로써 봄 3.0에서 이 문제가 해결되었다고 말합니다.

현상금이 단 하나의 답도 끌어내지 못한 것 같군요. 그래서 제가 이해한 것은 제한적으로 기록하겠습니다.

@Configuration
public class SpringConfig {

    @Bean 
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) 
    MyService myService() {
        return new MyService();
    }

    @Bean
    @Scope("request")
    public IndexBean indexBean() {
        return new IndexBean();
    }

    @Bean
    @Scope("request")
    public DetailBean detailBean() {
        return new DetailBean();
    }
}

public class IndexBean implements Serializable {

    @Inject MyService myService;

    public void doSomething() {
        myService.sayHello();
    }
}

public class MyService {
    public void sayHello() {
        System.out.println("Hello World!");
    }
}

그러면 Spring이 네이키드 마이서비스를 IndexBean에 주입하는 것이 아니라, 그것에 대한 직렬화 가능한 프록시를 주입하게 됩니다. (테스트해보니 효과가 있었습니다.)

그러나 스프링 설명서에는 다음과 같이 기록되어 있습니다.

사용할 필요가 없습니다.<aop:scoped-proxy/> Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ,singletons아니면prototypes에 대한 , . 이 에 를 를 ,BeanCreationException인양됩니다.

적어도 자바 기반 구성을 사용할 때, 빈과 그 프록시는 아주 잘 인스턴스화될 수 있습니다. 즉, 예외가 던져지지 않습니다.그러나 직렬화 가능성을 달성하기 위해 범위가 지정된 프록시를 사용하는 것은 그러한 프록시의 의도된 사용이 아닌 것 같습니다.그렇기 때문에, 저는 Spring이 그 "버그"를 수정하고 Java 기반 구성을 통해 범위가 지정된 프록시를 생성하는 것을 막을 수 있을지도 모른다고 우려합니다.

또한 다음과 같은 한계가 있습니다.프록시의 클래스 이름은 웹 응용 프로그램을 다시 시작한 후에 다릅니다(프록시의 클래스 이름은 해당 응용 프로그램을 구성하는 데 사용된 조언의 해시 코드를 기반으로 하며, 이는 인터셉터의 클래스 개체의 해시 코드에 따라 달라집니다).Class.hashCode는 Object를 재정의하지 않습니다.다시 시작하는 동안 안정적이지 않은 hashCode).따라서 직렬화된 세션을 다른 VM에서 사용하거나 재시작을 통해 사용할 수 없습니다.

저는 컨트롤러를 세션에서가 아니라 '싱글톤', 즉 애플리케이션별로 한 번씩' 범위를 지정하기를 기대합니다.

세션 범위 지정은 일반적으로 사용자별 정보 또는 사용자별 기능을 저장하는 데 더 많이 사용됩니다.

보통 저는 '사용자' 객체를 세션에 저장하고, 인증에 사용되는 콩 등을 저장합니다.바로 그겁니다.

aop 프록시를 사용하여 세션 범위에서 일부 사용자 데이터를 구성하는 스프링 문서를 살펴봅니다.

http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-other-injection

도움이 되기를 바랍니다.

저는 최근에 JSF와 Spring을 결합했습니다.저는 페이지를 지원하는 RichFaces와 JSF를 직렬화하는 @KeepAlive 기능을 사용합니다.제가 이 일을 하게 된 방법은 두 가지입니다.

1) JSF 백업 빈에서 @Component("session") 사용

2) 필요할 때마다 ELContext에서 콩을 가져오십시오. 이런 것들이 있습니다.

@SuppressWarnings("unchecked")
public static <T> T  getBean(String beanName) {
    return (T) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, beanName);
}

여러 대안을 모두 시도한 후에 제가 해야 할 일은 제 콩 정의에 op:scope-proxy를 추가하는 것뿐이라고 제안했고 그것은 작동하기 시작했습니다.

<bean id="securityService"
    class="xxx.customer.engagement.service.impl.SecurityContextServiceImpl">
    <aop:scoped-proxy/>
    <property name="identityService" ref="identityService" />
</bean>

보안 서비스는 뷰 범위가 지정된 내 관리되는 빈에 주입됩니다.이거 잘 되는 것 같네요.봄 문서에 따르면 이것은 콩의 창조물을 던져주는 것으로 되어 있습니다.securityService가 싱글톤이므로 예외입니다.하지만 이런 일은 일어나지 않을 것 같고 잘 작동합니다.이것이 버그인지 부작용이 무엇인지 확실하지 않습니다.

Session-Replication과 같이 서로 다른 JVM 간에도 Dynamic-Proxies 직렬화가 잘 작동합니다.

@Configuration public class SpringConfig {
@Bean 
@Scope(proxyMode = ScopedProxyMode.INTERFACES) 
MyService myService() {
    return new MyService();
}
.....

컨텍스트를 새로 고치기 전에 ApplicationContext의 ID만 설정하면 됩니다(org.springframework 참조).콩 공장지지하다.나열 가능한 기본 BeanFactory.setSerializationId(String))

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// all other initialisation part ...
// before! refresh
ctx.setId("portal-lasg-appCtx-id");
// now refresh ..
ctx.refresh();
ctx.start();

Spring-Version: 4.1.2에서 정상 작동합니다.풀어주다

언급URL : https://stackoverflow.com/questions/3180963/spring-session-scoped-beans-controllers-and-references-to-services-in-terms-o

반응형