2015-11-16 1 views
1

В большинстве весны Ботинок новых пользователей у меня есть проблема с @Autowired: DSpring загрузка @Autowired создание экземпляров на время выполнения

Я прочтенный большое количеством тем об этом аннотации здесь Но до сих пор не может найти правильное решение для моей проблемы.

Давайте предположим, что у нас есть эта весна загрузка иерархия:

@SpringBootApplication 
public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 
} 

класс, что мы хотим создать экземпляр каждый раз, когда это называется:

@Service 
public class TestWire { 
    public TestWire() { 
     System.out.println("INSTANCE CREATED: " + this); 
    } 
} 

Out получить контроллер, который создает новый объект SomeRepo каждый запроса :

@RestController 
public class CreatingRepo { 
    @RequestMapping("/") 
    public void postMessage() { 
     SomeRepo repo = new SomeRepo(); 
    } 
} 

И наконец, класс, который использует @Autowired для создания Te stWire экземпляры:

public class SomeRepo { 
    @Autowired 
    private TestWire testWire; 

    public SomeRepo() { 
     System.out.println(testWire.toString()); 
    } 
} 

Предположим, что мы делаем запрос GET на «/» несколько раз.

Таким образом, в результате TestWire класс isntantiate только тогда, когда проект строит и ни @Scope (значение = «прототип»), ни ProxyMode = ScopedProxyMode.TARGET_CLASS не поможет.

Любые идеи о создании новых экземпляров во время выполнения? Я имею в виду, как мы можем это сделать «Весной»? Без фабрик и других вещей, только Spring DI через аннотацию и настройку.

Обновление. Кусок трассировки стека, где экземпляр созданного:

2015-11-16 20:30:41.032 INFO 17696 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 
INSTANCE CREATED: [email protected] 
2015-11-16 20:30:41.491 INFO 17696 --- [   main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot[email protected]12f41634: startup date [Mon Nov 16 20:30:37 MSK 2015]; root of context hierarchy 
2015-11-16 20:30:41.566 INFO 17696 --- [   main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public void com.example.CreatingRepo.postMessage() 
+0

Проблема заключается в том, что вы используете ' new SomeRepo() ', поэтому экземпляр' SomeRepo' не управляется Spring. Если вам нужно/нужно получить новый экземпляр SomeRepo каждый раз, когда выполняется «CreateRepo # postMessage» и с помощью оператора «new», и пусть Spring управляет экземпляром компонента (это позволяет использовать возможности автопотока и другие весенние товары), вы может использовать '@ Configurable'. –

+0

@LuiggiMendoza Я изменил свой контроллер, теперь он использует '@ Autowire' для инъекции класса SomeRepo, который аннотируется с помощью' @ Configurable' и '@ Service'. Кажется, я использую инъекцию SomeRepo неправильно, потому что он все еще использует тот же экземпляр TestWire. У вас есть примеры или ссылки? – Supo

+1

Вы можете попробовать сделать некоторые исследования о том, как работает '@ Configurable', например, вам необходимо включить аспектное ткачество. –

ответ

4

Если я понял вас правильно, вы должны аннотировать SomeRepo так:

@Service 
@Scope(value = "prototype") 
public class SomeRepo { 
// ... 
} 

Вариант А:

Вместо инстанцировании класс с new SomeRepo(); вы задаете для него BeanFactory.getBean(...).

@RestController 
public class CreatingRepo { 
    @Autowired 
    BeanFactory beanFactory; 

    @RequestMapping("/") 
    public void postMessage() { 
     // instead of new SomeBean we get it from the BeanFactory 
     SomeRepo repo = beanFactory.getBean(SomeRepo.class); 
    } 
} 

Вариант B:

Вы также должны быть в состоянии получить Bean, как это (более paramters без beanFactory):

@RestController 
public class CreatingRepo { 

    @RequestMapping("/") 
    public void postMessage(SomeRepo repo) { 
     // instead of the BeanFactory and using new SomeRepo you can get it like this. 
    } 
} 
+0

Да, это было то, что я хочу, спасибо :) – Supo

+0

@ Супо странно, это противоречит тому, что вы спрашивали: * как можно мы делаем это в «Весеннем пути»? Без фабрик и других вещей, только Spring DI через аннотацию и настройку *. –

+0

@LuiggiMendoza, к сожалению, у меня нет времени прямо сейчас, чтобы лучше исследовать (5 часов до крайнего срока :)), но это для меня. Под фабриками я имею в виду немного другую вещь (где каждый раз, когда мы вызываем фабричный метод, мы вызываем явно «новый Bean»). Я не знал об этом типе создания бина (я имею в виду вне 'xml' config). Спасибо за вашу помощь, во всяком случае, я собираюсь попробовать дома в следующие выходные: D – Supo

Смежные вопросы