Как использовать шаблон проектирования цепочки ответственности в Spring

Java

Как использовать шаблон проектирования цепочки ответственности в Spring

Писательские навыки у автора пока неглубокие, если что не так, укажите великодушно, буду признателен

Эта статья не о примере дизайна использования цепочки ответственности в исходном коде Spring, а о том, как спроектировать собственную цепочку ответственности в Spring и как ее вызвать.

Как один из наших часто используемых шаблонов проектирования, шаблон проектирования «Цепочка ответственности» имеет широкий спектр применения.Например, при выполнении некоторого процесса или динамическом перехвате мы можем использовать шаблон проектирования «Цепь ответственности» для разработки требований, чтобы сделать наш проект И доступность, и масштабируемость будут очень хорошими.

Если вы до сих пор не знаете о цепочке ответственности, вы можете прочитать мою предыдущую запись в блогеШаблоны проектирования — шаблон цепочки ответственности

Как определить цепь

В Java-разработке, если мы хотим определить цепочку самостоятельно, это на самом деле очень просто, то есть определить абстрактный класс, затем определить несколько методов реализации, а затем установить его следующий атрибут, но как связать фреймворк с нашей цепочкой весной объединить его? На самом деле здесь используются три аннотации@Component,@Order,@PostConstruct.

  • @Component: передать наш подкласс руководству Spring
  • @Order: определить порядок нашей цепочки
  • @PostConstruct: объединяем наши цепочки при запуске программы

Далее давайте посмотрим на код напрямую, сначала посмотрим на абстрактный класс, на самом деле абстрактные классы цепочки ответственности в основном одинаковы.

 1public abstract class PrintChainPattern {
2
3    private PrintChainPattern next;
4
5    public final void print() {
6        String message = getMessage();
7
8        log.info("{} : {}",message,message);
9        if (getNext()!=null){
10            getNext().print();
11        }
12    }
13    public abstract String getMessage();
14}

Потом смотрим на класс, сзади четыре класса реализации, и возвращаем его по очереди.two,three,four.@OrderЦифры в аннотациях последовательно увеличиваются. Здесь демонстрируется только код первого класса реализации.

1@Order(1)
2@Component
3public class OnePrintChainPattern extends PrintChainPattern{
4    @Override
5    public String getMessage() {
6        return "one";
7    }
8}

Далее следует, как использовать Spring для сборки нашей цепочки.

 1@Configuration
2public class InitPrintChainPattern {
3
4    @Autowired
5    private List<PrintChainPattern> printChainPatterns;
6
7    @PostConstruct
8    private void initPrintChainPattern(){
9        Collections.sort(printChainPatterns, AnnotationAwareOrderComparator.INSTANCE);
10
11        int size = printChainPatterns.size();
12        for (int i = 0; i < size; i++) {
13            if (i == size-1){
14                printChainPatterns.get(i).setNext(null);
15            }else {
16                printChainPatterns.get(i).setNext(printChainPatterns.get(i+1));
17            }
18        }
19    }
20
21    public void print(int index){
22        printChainPatterns.get(index-1).print();
23    }
24}

Здесь мы видим, что в@PostConstructВ методе мы делаем две вещи

  1. будетListв соответствии с@OrderАннотации сортируются по номерам
  2. Установите следующее значение каждого узла по очереди

Итак, мы собрали цепочку. Далее, мы можем управлять этой цепочкой по желанию, например, следующим образом:print()В методе он выполняется с разных узлов в соответствии с разными переданными значениями.

Как использовать @Autowired в абстрактном классе

Выше мы объединили нашу цепочку, но если все наши подклассы имеют какой-то общий класс, то этот класс следует поместить в абстрактный класс. Так что, если этот класс мы хотим получить из контейнера Spring?

Например, у нас есть следующий класс, которым будет управлять Spring, и все наши подклассы должны использовать этот класс.

1@Bean
2public User setUser(){
3    return User.builder().name("张三").age(14).build();
4}

Его нужно определить только один раз в абстрактном классе, просто вsetметод плюс@AutowiredАннотации могут внедрять классы в контейнер Spring.

1private User user;
2
3@Autowired
4public void setUser(User user){
5    this.user = user;
6}

а затем вызовите непосредственно в подклассеgetUser()метод будет делать

1@Override
2public String getMessage() {
3    log.info("name:{},age:{}",getUser().getName(),getUser().getAge());
4    return "one";
5}

Как использовать @Autowired в классе enum

Зачем использовать в классе enum@Autowired, потому что я объединил шаблон проектирования цепочки ответственности и шаблон стратегии, когда составлял требования.Если вы не понимаете шаблон стратегии, вы можете прочитать мою предыдущую статью.Шаблоны проектирования — шаблоны стратегии. Мы можем использовать классы enum, чтобы сделать наш код более заметным.

Мы определяем простой класс перечисления для шаблона стратегии перечисления. Например, если мы хотим использовать класс в контейнере Spring, как нам его написать? например илиUserсвоего рода.

 1public enum  HumanEnum {
2
3    MAN("man"){
4        @Override
5        public void invoke() {
6            log.info("i am man");
7        }
8    },
9    WOMAN("woman"){
10        @Override
11        public void invoke() {
12            log.info("i am woman");
13        }
14    };
15
16    String value;
17
18    HumanEnum(String value){
19        this.value = value;
20    }
21
22    public abstract void invoke();
23}

Просто определите внутренний класс в классе перечисления, а затем назначьте введенный класс классу перечисления.

 1User user;
2
3public void setUse(User user){
4    this.user = user;
5}
6
7@Component
8public static class HumanEnumInjector{
9
10    @Autowired
11    private  User user;
12
13    @PostConstruct
14    public void setValue(){
15        for (HumanEnum humanEnum : EnumSet.allOf(HumanEnum.class)){
16            humanEnum.setUse(user);
17        }
18    }
19}

Кодовый адрес этой статьи

Суммировать

Три характеристики объектно-ориентированного подхода: инкапсуляция, наследование, полиморфизм.

  1. Большинство шаблонов проектирования развиваются вокруг трех характеристик объектно-ориентированного подхода.
  2. @AutowiredЕго тоже можно определить на методе, но просто было принято определять его на поле
  3. Обратите внимание на основы, и сложный дизайн должен быть собран воедино с помощью простого дизайна.