[SPRING] Spring에서 순서대로 콩을 인스턴스화 하시겠습니까?
SPRINGSpring에서 순서대로 콩을 인스턴스화 하시겠습니까?
Spring에서 인스턴스화의 순서를 설정할 수 있습니까?
@DependsOn을 사용하고 싶지 않고 Ordered 인터페이스를 사용하고 싶지 않습니다. 인스턴스화 명령이 필요합니다.
@Order 주석의 다음 사용법이 작동하지 않습니다.
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
/**
* Order does not work here
*/
public class OrderingOfInstantiation {
public static class MyBean1 {{
System.out.println(getClass().getSimpleName());
}}
public static class MyBean2 {{
System.out.println(getClass().getSimpleName());
}}
@Configuration
public static class Config {
@Bean
@Order(2)
public MyBean1 bean1() {
return new MyBean1();
}
@Bean
@Order(1)
public MyBean2 bean2() {
return new MyBean2();
}
}
public static void main(String[] args) {
new AnnotationConfigApplicationContext(Config.class);
}
}
콩은 여전히 사전 식 순서로 인스턴스화됩니다.
왜 여기서 작동하지 않습니까?
어쨌든 사전 편찬 명령에 의존 할 수 있습니까?
최신 정보
나는 창조의 질서를 제공 할 수있는 해결책을 원합니다.
목표는 구성 수준에서 정확한 순서로 콜렉션을 채우는 것입니다. 종속 - 작업과 일치하지 않습니다. Spring이 인스턴스화 명령을 내리지 않는 이유에 대한 "설명"도 작업과 일치하지 않습니다.
주문은 주문을 의미합니다 :)
해결법
-
==============================
1.@Order javadoc에서
@Order javadoc에서
그래서 스프링을 만들면 콩을 만들 때 @Order ()를 따르지 않는다고 생각합니다.
그러나 콜렉션을 채우기 만하면됩니다.
import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import java.lang.annotation.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; @Configuration public class OrderingOfInstantiation { public static void main(String[] args) { new AnnotationConfigApplicationContext(OrderingOfInstantiation.class); } @Component @CollectionOrder(collection = "myBeans", order = 1) public static class MyBean1 {{ System.out.println(getClass().getSimpleName()); }} @Component @CollectionOrder(collection = "myBeans", order = 2) public static class MyBean2 {{ System.out.println(getClass().getSimpleName()); }} @Configuration public static class CollectionsConfig { @Bean List<Object> myBeans() { return new ArrayList<>(); } } // PopulateConfig will populate all collections beans @Configuration public static class PopulateConfig implements ApplicationContextAware { @SuppressWarnings("unchecked") @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Multimap<String, Object> beansMap = MultimapBuilder.hashKeys().arrayListValues().build(); // get all beans applicationContext.getBeansWithAnnotation(CollectionOrder.class) .values().stream() // get CollectionOrder annotation .map(bean -> Pair.of(bean, bean.getClass().getAnnotation(CollectionOrder.class))) // sort by order .sorted((p1, p2) -> p1.getRight().order() - p2.getRight().order()) // add to multimap .forEach(pair -> beansMap.put(pair.getRight().collection(), pair.getLeft())); // and add beans to collections beansMap.asMap().entrySet().forEach(entry -> { Collection collection = applicationContext.getBean(entry.getKey(), Collection.class); collection.addAll(entry.getValue()); // debug System.out.println(entry.getKey() + ":"); collection.stream() .map(bean -> bean.getClass().getSimpleName()) .forEach(System.out::println); }); } } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented public @interface CollectionOrder { int order() default 0; String collection(); } }
인스턴스화 순서는 변경되지 않지만 순서가 지정된 콜렉션을 가져옵니다.
-
==============================
2.특정 빈이 다른 빈보다 먼저 생성되도록하려면 @DependsOn 주석을 사용할 수 있습니다.
특정 빈이 다른 빈보다 먼저 생성되도록하려면 @DependsOn 주석을 사용할 수 있습니다.
@Configuration public class Configuration { @Bean public Foo foo() { ... } @Bean @DependsOn("foo") public Bar bar() { ... } }
이것이 주문을 설정하지 않는다는 것을 명심하십시오. 빈 "foo"가 "bar"앞에 만들어지는 것만을 보장합니다. @DependsOn에 대한 JavaDoc
-
==============================
3.MyBean1 및 MyBean2 클래스에서 정적을 제거하면 대부분의 경우 Spring을 사용할 필요가 없을 때 Spring의 기본값이 각 Bean의 단일 인스턴스를 인스턴스화하기 때문에 (예 : Singleton과 유사하게) 순서에 따라 순서를 지정할 수 있습니다. .
MyBean1 및 MyBean2 클래스에서 정적을 제거하면 대부분의 경우 Spring을 사용할 필요가 없을 때 Spring의 기본값이 각 Bean의 단일 인스턴스를 인스턴스화하기 때문에 (예 : Singleton과 유사하게) 순서에 따라 순서를 지정할 수 있습니다. .
트릭은 MyBean1과 MyBean2를 @Bean으로 선언하고 순서를 적용하기 위해 bean1의 초기화 메소드 내에서 bean2의 bean 초기화 메소드를 호출하여 bean1에서 bean2 로의 암시 적 종속성을 작성합니다.
예 :
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; /** * Order does not work here */ public class OrderingOfInstantiation { interface MyBean{ default String printSimpleName(){ System.out.println(getClass().getSimpleName()); } } public class MyBean1 implments MyBean{ public MyBean1(){ pintSimpleName(); } } public class MyBean2 implments MyBean{ public MyBean2(){ pintSimpleName(); } } public class MyBean3 implments MyBean{ public MyBean3(){ pintSimpleName(); } } public class MyBean4 implments MyBean{ public MyBean4(){ pintSimpleName(); } } public class MyBean5 implments MyBean{ public MyBean5(){ pintSimpleName(); } } @Configuration public class Config { @Bean MyBean1 bean1() { //This will cause a a dependency on bean2 //forcing it to be created before bean1 bean2(); return addToAllBeans(new MyBean1()); } @Bean MyBean2 bean2() { //This will cause a a dependency on bean3 //forcing it to be created before bean2 bean3(); //Note: This is added just to explain another point //Calling the bean3() method a second time will not create //Another instance of MyBean3. Spring only creates 1 by default //And will instead look up the existing bean2 and return that. bean3(); return addToAllBeans(new MyBean2()); } @Bean MyBean3 bean3(){ return addToAllBeans(new MyBean3()); } @Bean MyBean4 bean4(){ return addToAllBeans(new MyBean4()); } @Bean MyBean5 bean5(){ return addToAllBeans(new MyBean5()); } /** If you want each bean to add itself to the allBeans list **/ @Bean List<MyBean> allBeans(){ return new ArrayList<MyBean>(); } private <T extends MyBean> T addToAllBeans(T aBean){ allBeans().add(aBean); return aBean; } } public static void main(String[] args) { new AnnotationConfigApplicationContext(Config.class); } }
from https://stackoverflow.com/questions/36187063/instantiate-beans-in-order-in-spring by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Security의 기본 필터 스택에서 하나의 필터를 삭제하는 방법? (0) | 2019.04.11 |
---|---|
[SPRING] 봄 석영 크론 작업을 동적으로 스케줄링 하시겠습니까? (0) | 2019.04.11 |
[SPRING] 봄 - 파일 다운로드 및 리디렉션 (0) | 2019.04.11 |
[SPRING] spring aspectj - 외부 항아리를 짜는 컴파일 시간 (0) | 2019.04.11 |
[SPRING] STS를 사용하여 새로운 웹 어플리케이션 프로젝트를 생성 할 때 Spring MVC 프로젝트를 찾을 수 없습니까? (0) | 2019.04.10 |