Регистрирует ли bean внутри класса @Component уважение @Scope?

На этом веб-сайте говорится, что компоненты, зарегистрированные внутри классов компонентов, не проксированы cglib и не проходят через весенний контейнер. Так ли это означает, что если я зарегистрирую компонент внутри класса компонента (сниппет ниже), добавление @Scope ("запрос") не будет иметь никакого значения, и новый экземпляр AnotherBean будет всегда создаваться всякий раз, когда testBean.anotherBean() какой-то внешний класс?

@Component
public class TestBean {

 @Bean
 @Scope("request")
 public AnotherBean anotherBean() {
 return new AnotherBean();
 }
}
1 ответ

Компонент, который не является cglib proxied, является самим @Component, а не компонентом, зарегистрированным с @Bean аннотации @Bean. Если вы явно не вызываете метод anotherBean, это не будет иметь никакого значения, потому что прокси используется для возврата компонента, когда @Bean метод, аннотированный с помощью @Bean. См. Пример

testBeanComponent не прокси-сервер cglib:

@Component
public class TestBeanComponent {

 @Bean
 @Scope("request")
 public AnotherBeanComponent anotherBeanComponent() {
 return new AnotherBeanComponent();
 }
}

testBeanConfiguration - cglib proxied:

@Configuration
public class TestBeanConfiguration {

 @Bean
 @Scope("request")
 public AnotherBeanConfiguration anotherBeanConfiguration() {
 return new AnotherBeanConfiguration();
 }
}

Что это значит:

@Service
public class TestService {

 @Autowired //Inject a normal bean
 private TestBeanComponent testBeanComponent; 

 @Autowired //Inject a proxy
 private TestBeanConfiguration testBeanConfiguration;

 public void test() {
 //Calling anotherBeanComponent always return a new instance of AnotherBeanComponent
 testBeanComponent.anotherBeanComponent()
 .equals(testBeanComponent.anotherBeanComponent()); // is false

 //Calling anotherBeanConfiguration return the bean managed by the container
 testBeanConfiguration.anotherBeanConfiguration()
 .equals(testBeanConfiguration.anotherBeanConfiguration()); // is true
 }
}

Но если вы используете инъекционный компонент вместо использования метода, все будет работать так, как вы ожидали:

@Service
public class TestService2 {

 @Autowired //Inject a proxy with scope request
 private AnotherBeanComponent anotherBeanComponent; 

 @Autowired //Inject a proxy with scope request
 private AnotherBeanConfiguration anotherBeanConfiguration;

}

licensed under cc by-sa 3.0 with attribution.