Применение AspectJ с переплетением времени компиляции к приложению Spring Boot без внешних зависимостей - PullRequest
1 голос
/ 05 апреля 2019

Я настраиваю приложение SpringBoot , которое должно выполняться в командной строке.Приложение содержит несколько CommandLineRunners, которые запускают свою особую логику, если нужная опция была передана через выполнение командной строки.Я использую Gradle в качестве инструмента сборки.

У каждого бегуна был один метод инициализации для разбора параметров и распечатки оператора справки, если ни один из вариантов не былмимо, который я передал в аспект-класс.
И вот так начинается проблема.

Сначала я уже успешно попробовал с Spring AOP , но это не такЭто не вариант, потому что я хочу связать частные методы с моими аспектами.Поэтому я должен использовать более мощный AspectJ для достижения этой цели.

К сожалению, AspectJ Weaving-Time-Weaving не вариант для меня, потому что он должен пройтив jvm-аргументах командной строки, когда исполняется jar, чего я хочу избежать.

Итак, из того, что я видел сейчас, есть только AspectJ Компиляция во время компиляции и AspectJ Плетение после компиляции осталось.

AspectJ Компиляция во время компиляции выглядит лучше всего для меня, но, к сожалению, нужно применить плагин, подобный следующему от io.freefair.
Ссылка: https://plugins.gradle.org/plugin/io.freefair.aspectj.compile-time-weaving
Я попробовал это, и это сработало должным образом, но моя цель - избежать добавления внешних зависимостей в мой проект, поэтому я пытаюсь найти решение из Springили стандартное семейство Java.

То же самое для ткачества после компиляции.

Каждый учебник или ответ, касающийся ткачества во время компиляции, который я читал, касался применения плагина.Мне интересно, что я не нашел метода для разрешения моего варианта использования, за исключением плагина io.freefair, описанного выше.

MainClass:

@SpringBootApplication
@ImportResource("classpath:spring/applicationContext.xml")
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
public class MainClass {

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args) {
        SpringApplication.run(MainClass.class, args);
    }
}

Мой класс аспектов выглядит следующим образом:

@Aspect
public class ConfigurationsAspect {

    private static final Logger logger = Logger.getLogger(ConfigurationsAspect.class);

    @Autowired
    private ConnectionWrapper connection;

    @Autowired
    private OptionHandler optionHandler;

    /**
     * Closes the connection to the Server if there were an initialized connection.
     */
    @After("execution(void tools.cli.MainClass.main(*))")
    public void closeConnection() {
        if (this.connection.isConnected()) {
            logger.debug("Closing connection");
            this.connection.close();
        }
    }                                                                                                                       

    /**
     * Parses the options if not parsed before.
     * 
     * @param jp The actual point of execution.
     */
    @Before("execution(* tools.runners.tasks.*.run(*))")
    public void parseOptions(JoinPoint jp) {
        if (!this.optionHandler.isParsed()) {
            String[] args = (String[]) jp.getArgs()[0];
            this.optionHandler.parseParameters(args);
        }
    }
}

Связанные bean-компоненты описаны в applicationContext.xml как (Snippet):

    <bean class="tools.aspects.ConfigurationsAspect" factory-method="aspectOf"/>    

    <bean class="tools.cli.options.OptionHandler"/>

    <bean class="tools.connection.ConnectionWrapper" />

Мой build.gradle выглядит следующим образом (Snippet):

plugins {
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id 'java'
}

apply plugin: 'application'
apply plugin: 'io.spring.dependency-management'

dependencies {
    compile('commons-io:commons-io:2.5')    
    compile('commons-cli:commons-cli:1.4')
    compile('org.springframework.boot:spring-boot-starter')

    compile('org.springframework:spring-oxm')
    testCompile('org.springframework:spring-oxm')

    compile 'org.aspectj:aspectjrt:1.9.2'
    compile 'org.aspectj:aspectjweaver:1.9.2'
}

Я получаю следующее сообщение об ошибке, когда я не применяю плагин io.freefair.

ERROR org.springframework.boot.SpringApplication: 858 - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tools.aspects.ConfigurationsAspect#0' defined in class path resource [spring/applicationContext.xml]: No matching factory method found: factory method 'aspectOf()'. Check that a method with the specified name exists and that it is static.

AspectJ должен создать экземпляр моего ConfigurationsAspect и вставить аспект aspectOf () - метод, который Springпоиск, если он работал правильно.

Вывод на мой вопрос:

Есть ли возможность достичь AspectJ время компиляции (или время посткомпиляции)Ткачество без применения внешних зависимостей?

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


Спасибо и привет.

...