1. введение
В этом кратком уроке мы собираемся интегрировать Drools с Spring. Если вы только начинаете работать со слюнями, ознакомьтесь с этой вступительной статьей.
2. Зависимости Maven
Давайте начнем с добавления следующих зависимостей к вашему pom.xml файл:
org.drools drools-core 7.0.0.Final org.kie kie-spring 7.0.0.Final
Последние версии можно найти здесь для drools-core и здесь для kie-spring .
3. Исходные Данные
Давайте теперь определим данные, которые будут использоваться в нашем примере. Мы собираемся рассчитать стоимость поездки, основываясь на пройденном расстоянии и флаге ночной доплаты.
Вот простой объект, который будет использоваться в качестве Факта:
public class TaxiRide { private Boolean isNightSurcharge; private Long distanceInMile; // standard constructors, getters/setters }
Давайте также определим еще один бизнес-объект, который будет использоваться для представления тарифов:
public class Fare { private Long nightSurcharge; private Long rideFare; // standard constructors, getters/setters }
Теперь давайте определим бизнес-правило расчета тарифов на такси:
global com.baeldung.spring.drools.model.Fare rideFare; dialect "mvel" rule "Calculate Taxi Fare - Scenario 1" when taxiRideInstance:TaxiRide(isNightSurcharge == false && distanceInMile < 10); then rideFare.setNightSurcharge(0); rideFare.setRideFare(70); end
Как мы видим, определено правило для расчета общей стоимости данной Поездки на такси .
Это правило принимает объект Taxi Ride и проверяет, является ли Ночной доплатой атрибут false и расстояние в миле значение атрибута меньше 10, затем вычисляет тариф как 70 и устанавливает свойство nightSurcharge равным 0.
Рассчитанный выход устанавливается в Fare object для дальнейшего использования.
4. Весенняя Интеграция
4.1. Конфигурация Пружинных Бобов
Теперь перейдем к весенней интеграции.
Мы собираемся определить класс конфигурации Spring bean, который будет отвечать за создание экземпляра компонента TaxiFareCalculatorService bean и его зависимостей:
@Configuration @ComponentScan("com.baeldung.spring.drools.service") public class TaxiFareConfiguration { private static final String drlFile = "TAXI_FARE_RULE.drl"; @Bean public KieContainer kieContainer() { KieServices kieServices = KieServices.Factory.get(); KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); kieFileSystem.write(ResourceFactory.newClassPathResource(drlFile)); KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem); kieBuilder.buildAll(); KieModule kieModule = kieBuilder.getKieModule(); return kieServices.newKieContainer(kieModule.getReleaseId()); } }
KieServices – это синглтон, который действует как единая точка входа для получения всех услуг, предоставляемых Kie. KieServices извлекается с помощью KieServices.Factory.get().
Далее нам нужно получить KieContainer , который является заполнителем для всех объектов, которые нам нужны для запуска механизма правил.
KieContainer строится с помощью других компонентов, включая KieFileSystem, Kie Builder, и KieModule.
Давайте перейдем к созданию KieModule , который является контейнером всех ресурсов, необходимых для определения знаний правил, известных как KieBase.
KieModule kieModule = kieBuilder.getKieModule();
Kielbasa – это хранилище, которое содержит все знания, связанные с приложением, такие как правила, процессы, функции, модели типов, и оно скрыто внутри KieModule . Файл KieBase можно получить из файла KieContainer.
После создания KieModule мы можем перейти к созданию KieContainer – , который содержит KieModule , где был определен KieBase . KieContainer создается с помощью модуля:
KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());
4.2. Весенняя служба
Давайте определим класс сервиса, который выполняет фактическую бизнес-логику, передавая объект Fact движку для обработки результата:
@Service public class TaxiFareCalculatorService { @Autowired private KieContainer kieContainer; public Long calculateFare(TaxiRide taxiRide, Fare rideFare) { KieSession kieSession = kieContainer.newKieSession(); kieSession.setGlobal("rideFare", rideFare); kieSession.insert(taxiRide); kieSession.fireAllRules(); kieSession.dispose(); return rideFare.getTotalFare(); } }
Наконец, KieSession создается с помощью экземпляра KieContainer . Экземпляр KieSession – это место, куда можно вставить входные данные. KieSession взаимодействует с движком для обработки фактической бизнес-логики, определенной в правиле, основанном на вставленных фактах.
Глобальная (как и глобальная переменная) используется для передачи информации в движок. Мы можем установить Глобальный параметр с помощью set Global(“ключ”, значение); в этом примере мы установили объект Fire как Глобальный для хранения рассчитанного тарифа такси.
Как мы обсуждали в разделе 4, a Правило требует данных для работы с . Мы вставляем Факт в сеанс с помощью KieSession .insert(taxiRide);
Как только мы закончим с настройкой входного Факта, мы можем запросить движок для выполнения бизнес-логики, вызвав fireAllRules().
Наконец, нам нужно очистить сеанс, чтобы избежать утечки памяти, вызвав метод dispose () .
5. Пример в действии
Теперь мы можем подключить пружинный контекст и увидеть в действии, что Drools работает так, как ожидалось:
@Test public void whenNightSurchargeFalseAndDistLessThan10_thenFixWithoutNightSurcharge() { TaxiRide taxiRide = new TaxiRide(); taxiRide.setIsNightSurcharge(false); taxiRide.setDistanceInMile(9L); Fare rideFare = new Fare(); Long totalCharge = taxiFareCalculatorService.calculateFare(taxiRide, rideFare); assertNotNull(totalCharge); assertEquals(Long.valueOf(70), totalCharge); }
6. Заключение
В этой статье мы узнали об интеграции Drools Spring с простым прецедентом использования.
Как всегда, реализация примера и фрагменты кода доступны на GitHub .