В Spring 3.1 есть способ автоматически заполнять типизированный список, который очень удобен, когда вы хотите немного отменить разделение и очистку в вашем коде.
Чтобы показать вам, как это работает, я реализую простую цепочку ответственности, которая позаботится о печати некоторых поздравлений для прошедшего пользователя.
Давайте начнем с (единственного) класса домена, который у нас есть, Пользователь:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
 | 
package com.marco.springchain;public class User {        private final String name;        private final char gender;        public User(String name, char gender) {                super();                this.name = name;                this.gender = gender;        }        public String getName() {                return name;        }        public char getGender() {                return gender;        }} | 
Затем мы создаем интерфейс, который определяет тип объектов нашей команды, которые будут использоваться в нашей цепочке:
| 
 1 
2 
3 
4 
5 
 | 
package com.marco.springchain;public interface Printer {        void print(User user);} | 
Это универсальный класс (шаблон) для реализации принтера.
 org.springframework.core.Ordered используется, чтобы сообщить AnnotationAwareOrderComparator, как мы хотим, чтобы наш список был упорядочен. 
Вам не нужно реализовывать интерфейс Ordered и переопределять метод getOrder, если вам не нужна цепочка для выполнения порядка выполнения.
  Также обратите внимание, что этот абстрактный класс возвращает Ordered.LOWEST_PRECEDENCE , потому что я хочу, чтобы некоторые команды Printer просто выполнялись в конце цепочки, и мне нет дела до их порядка выполнения (все будет ясно после, обещаю!). 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 | 
package com.marco.springchain;import org.springframework.core.Ordered;public abstract class <code>GenericPrinter </code>implements Printer, Ordered {        public void print(User user) {                String prefix = 'Mr';                if (user.getGender() == 'F') {                        prefix = 'Mrs';                }                System.out.println(getGreeting() + ' ' + prefix + ' ' + user.getName());        }        protected abstract String getGreeting();        public int getOrder() {                return Ordered.LOWEST_PRECEDENCE;        }} | 
  Это наша первая настоящая команда Принтер.  Я хочу, чтобы это имело абсолютный приоритет в цепочке, поэтому порядок HIGHEST_PRECEDENCE . 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 | 
package com.marco.springchain;import org.springframework.core.Ordered;import org.springframework.stereotype.Component;@Componentpublic class HelloPrinter extends GenericPrinter {        private static final String GREETING = 'Hello';        @Override        protected String getGreeting() {                return GREETING;        }        @Override        public int getOrder() {                return Ordered.HIGHEST_PRECEDENCE;        }} | 
  WelcomePrinter который будет выполнен как первая команда ( после старших команд). 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
 | 
package com.marco.springchain;import org.springframework.stereotype.Component;@Componentpublic class WelcomePrinter extends GenericPrinter {        private static final String GREETING = 'Welcome to the autowired chain';        @Override        protected String getGreeting() {                return GREETING;        }        @Override        public int getOrder() {                return 1;        }} | 
  GoodbyePrinter будет выполняться как вторая команда 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
 | 
package com.marco.springchain;import org.springframework.stereotype.Component;@Componentpublic class GoodbyePrinter extends GenericPrinter {        private static final String GREETING = 'Goodbye';        @Override        protected String getGreeting() {                return GREETING;        }        @Override        public int getOrder() {                return 2;        }} | 
  Эти 2 команды должны быть выполнены после других, но мне не важен их конкретный порядок, поэтому я не буду переопределять метод getOrder, оставляя GenericPrinter для возврата Ordered.LOWEST_PRECEDENCE для обоих. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
 | 
package com.marco.springchain;import org.springframework.stereotype.Component;@Componentpublic class CleaningMemoryPrinter extends GenericPrinter {        private static final String GREETING = 'Cleaning memory after';        @Override        protected String getGreeting() {                return GREETING;        }} | 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
 | 
package com.marco.springchain;import org.springframework.stereotype.Component;@Componentpublic class CleaningSpacePrinter extends GenericPrinter {        private static final String GREETING = 'Cleaning space after';        @Override        protected String getGreeting() {                return GREETING;        }} | 
Это контекст цепочки.
  Spring будет сканировать (см. Spring-config.xml) пакет, указанный в файле конфигурации, он увидит типизированный List<Printer> ( List<Printer> ) и заполнит список экземпляром любого @Component который реализует тип Принтер. 
  Чтобы упорядочить список, мы используем AnnotationAwareOrderComparator.INSTANCE который использует метод getOrder для переупорядочения списка ( объект с наименьшим значением имеет наивысший приоритет (в некоторой степени аналогичный значениям «загрузка при запуске» сервлета ) ). 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
 | 
package com.marco.springchain;import java.util.Collections;import java.util.List;import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.annotation.AnnotationAwareOrderComparator;import org.springframework.stereotype.Component;@Componentpublic class PrinterChain {        @Autowired        private List<Printer> printers;        @PostConstruct        public void init() {                Collections.sort(printers, AnnotationAwareOrderComparator.INSTANCE);        }        public void introduceUser(User user) {                for (Printer printer : printers) {                        printer.print(user);                }        }} | 
Spring-config.xml в src / main / resources.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
 | 
<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans'       xsi:schemaLocation='  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd' default-lazy-init='true'>    <context:component-scan base-package='com.marco.springchain'/></beans> | 
Наконец, основной класс для тестирования нашей цепочки.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
 | 
package com.marco.springchain;import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainTest {        public static void main(String[] args) {                ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext('spring-config.xml');                PrinterChain printerChain = (PrinterChain) context.getBean('printerChain');                printerChain.introduceUser(new User('Marco Castigliego', 'M'));                printerChain.introduceUser(new User('Julie Marot', 'F'));        }} | 
ВЫХОД:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
 | 
Hello Mr Marco CastigliegoWelcome to the autowired chain Mr Marco CastigliegoGoodbye Mr Marco CastigliegoCleaning space after Mr Marco CastigliegoCleaning memory after Mr Marco CastigliegoHello Mrs Julie MarotWelcome to the autowired chain Mrs Julie MarotGoodbye Mrs Julie MarotCleaning space after Mrs Julie MarotCleaning memory after Mrs Julie Marot | 
Надеюсь, вам понравился пример.
Ссылка: цепь ответственности с использованием Spring @Autowired List от нашего партнера по JCG Марко Кастильего из блога « Удалить дубликаты и исправить дурные имена» .