[SPRING] @Scope ( "prototype") 빈 범위는 새 빈을 생성하지 않습니다.
SPRING@Scope ( "prototype") 빈 범위는 새 빈을 생성하지 않습니다.
컨트롤러에 주석이 달린 프로토 타입 빈을 사용하고 싶습니다. 그러나 봄은 싱글 톤 빈을 대신 생성합니다. 그 코드는 다음과 같습니다.
@Component
@Scope("prototype")
public class LoginAction {
private int counter;
public LoginAction(){
System.out.println(" counter is:" + counter);
}
public String getStr() {
return " counter is:"+(++counter);
}
}
컨트롤러 코드 :
@Controller
public class HomeController {
@Autowired
private LoginAction loginAction;
@RequestMapping(value="/view", method=RequestMethod.GET)
public ModelAndView display(HttpServletRequest req){
ModelAndView mav = new ModelAndView("home");
mav.addObject("loginAction", loginAction);
return mav;
}
public void setLoginAction(LoginAction loginAction) {
this.loginAction = loginAction;
}
public LoginAction getLoginAction() {
return loginAction;
}
}
속도 템플릿 :
LoginAction counter: ${loginAction.str}
Spring config.xml에서 구성 요소 검색을 사용할 수 있습니다.
<context:annotation-config />
<context:component-scan base-package="com.springheat" />
<mvc:annotation-driven />
매번 증가한 횟수가 증가하고 있습니다. 내가 어디로 잘못 가고 있는지 알 수 없다!
최신 정보
@gkamal에 의해 제안 된 것처럼, 나는 HomeController webApplicationContext-aware를 만들었고 문제를 해결했다.
업데이트 된 코드 :
@Controller
public class HomeController {
@Autowired
private WebApplicationContext context;
@RequestMapping(value="/view", method=RequestMethod.GET)
public ModelAndView display(HttpServletRequest req){
ModelAndView mav = new ModelAndView("home");
mav.addObject("loginAction", getLoginAction());
return mav;
}
public LoginAction getLoginAction() {
return (LoginAction) context.getBean("loginAction");
}
}
해결법
-
==============================
1.범위 프로토 타입은 인스턴스에 대해 봄 (getBean 또는 종속성 삽입)을 요청할 때마다 새 인스턴스를 만들고 그에 대한 참조를 제공한다는 것을 의미합니다.
범위 프로토 타입은 인스턴스에 대해 봄 (getBean 또는 종속성 삽입)을 요청할 때마다 새 인스턴스를 만들고 그에 대한 참조를 제공한다는 것을 의미합니다.
귀하의 예제에서 LoginAction의 새로운 인스턴스가 생성되어 HomeController에 삽입됩니다. LoginAction을 주입 할 다른 컨트롤러가있는 경우 다른 인스턴스가 생성됩니다.
각 호출마다 다른 인스턴스를 원한다면 매번 getBean을 호출해야한다. 싱글 톤 빈에 주입하면이를 달성하지 못할 것이다.
-
==============================
2.컨트롤러에 주입 된 bean이 프로토 타입 범위에 있다고해서 컨트롤러가된다는 것을 의미하지는 않는다!
컨트롤러에 주입 된 bean이 프로토 타입 범위에 있다고해서 컨트롤러가된다는 것을 의미하지는 않는다!
-
==============================
3.@controller는 싱글 톤 객체이고, 프로토 타입 빈을 싱글 톤 클래스에 삽입하면 프로토 타입 bean을 싱글 톤으로 만들 것이다. lookup-method 프로퍼티를 사용하여 실제로 호출 할 때마다 프로토 타입 빈의 새로운 인스턴스를 만든다.
@controller는 싱글 톤 객체이고, 프로토 타입 빈을 싱글 톤 클래스에 삽입하면 프로토 타입 bean을 싱글 톤으로 만들 것이다. lookup-method 프로퍼티를 사용하여 실제로 호출 할 때마다 프로토 타입 빈의 새로운 인스턴스를 만든다.
-
==============================
4.Spring 2.5부터는 매우 쉽고 (우아한) 방법이 있습니다.
Spring 2.5부터는 매우 쉽고 (우아한) 방법이 있습니다.
params proxyMode 및 @Scope 주석의 값을 변경할 수 있습니다.
이 트릭을 사용하면 싱글 톤 빈 안에 프로토 타입이 필요할 때마다 여분의 코드를 작성하거나 ApplicationContext를 삽입하지 않아도됩니다.
예:
@Service @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS) public class LoginAction {}
컨트롤러가 싱글 톤 임에도 불구하고 위의 설정을 사용하면 HomeController 내부의 LoginAction은 항상 프로토 타입입니다.
-
==============================
5.nicholas.hauschild가 언급 한 것처럼 스프링 컨텍스트를 주입하는 것은 좋은 생각이 아닙니다. 귀하의 경우에는 @Scope ( "request")로 해결할 수 있습니다. 하지만 컨트롤러 메소드에서 LoginAction의 여러 인스턴스가 필요하다고 가정 해 보겠습니다. 이 경우 Supplier (스프링 4 솔루션) 빈을 만드는 것이 좋습니다.
nicholas.hauschild가 언급 한 것처럼 스프링 컨텍스트를 주입하는 것은 좋은 생각이 아닙니다. 귀하의 경우에는 @Scope ( "request")로 해결할 수 있습니다. 하지만 컨트롤러 메소드에서 LoginAction의 여러 인스턴스가 필요하다고 가정 해 보겠습니다. 이 경우 Supplier (스프링 4 솔루션) 빈을 만드는 것이 좋습니다.
@Bean public Supplier<LoginAction> loginActionSupplier(LoginAction loginAction){ return () -> loginAction; }
그런 다음 컨트롤러에 주입합니다.
@Controller public class HomeController { @Autowired private Supplier<LoginAction> loginActionSupplier;
-
==============================
6.ApplicationContextAware를 사용하면 Spring (당신이 문제 일 수도 있고 아닐 수도 있음)에 묶여있다. LoginActionFactory를 전달하는 것이 좋습니다. LoginActionFactory는 필요할 때마다 LoginAction의 새 인스턴스를 요청할 수 있습니다.
ApplicationContextAware를 사용하면 Spring (당신이 문제 일 수도 있고 아닐 수도 있음)에 묶여있다. LoginActionFactory를 전달하는 것이 좋습니다. LoginActionFactory는 필요할 때마다 LoginAction의 새 인스턴스를 요청할 수 있습니다.
-
==============================
7.@Scope ( "request")를 사용하여 각 요청에 대해 빈을 얻거나 @Scope ( "session")을 사용하여 각 세션 'user'에 대한 빈을 얻는다.
@Scope ( "request")를 사용하여 각 요청에 대해 빈을 얻거나 @Scope ( "session")을 사용하여 각 세션 'user'에 대한 빈을 얻는다.
-
==============================
8.당신의 컨트롤러는 또한 @Scope ( "prototype") 정의가 필요하다.
당신의 컨트롤러는 또한 @Scope ( "prototype") 정의가 필요하다.
이렇게 :
@Controller @Scope("prototype") public class HomeController { ..... ..... ..... }
from https://stackoverflow.com/questions/7621920/scopeprototype-bean-scope-not-creating-new-bean by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring 데이터 저장소의 커스텀 메소드 구현 및 REST를 통한 노출 (0) | 2018.12.08 |
---|---|
[SPRING] Spring Data JPA GROUP BY 쿼리에서 커스텀 객체를 반환하는 방법 (0) | 2018.12.07 |
[SPRING] 컨텍스트에서 여러 패키지 : 구성 요소 검사, 봄 구성 (0) | 2018.12.07 |
[SPRING] Spring에서 ContextLoaderListener의 역할 / 목적은 무엇입니까? (0) | 2018.12.07 |
[SPRING] com.mysql.jdbc.exceptions.jdbc4.CommunicationsException : 통신 링크 실패 소프트웨어로 인한 연결 중단 : recv failed [duplicate] (0) | 2018.12.07 |