Проектирование библиотеки Java с помощью Spring
Я извлекаю некоторые функции из существующей программы в отдельную библиотеку.
Эта программа использует Spring для инъекций зависимостей и других задач, и я также хотел бы использовать ее в библиотеке.
Эта библиотека должна контролировать файловую систему для изменений, поэтому для ее запуска будет создан какой-то отдельный поток.
Я не знаю, какие мои параметры предназначены для инициализации библиотеки:
-
Как инициализировать библиотечный контекст? Я не могу предположить, что пользователи библиотеки также будут использовать Spring, но я могу распространять Spring с помощью библиотеки.
-
Как мне управлять потоком мониторинга файловой системы? Является ли хорошим дизайном ожидать, что программа создаст основной класс библиотеки и инициирует вызов или что-то в этом роде?
Ответы
Ответ 1
Как инициализировать библиотечный контекст? Я не могу предположить, что пользователи библиотеки также будут использовать Spring, но я могу распространять Spring с помощью библиотеки.
Это для вашей библиотеки, чтобы создать Spring способ, которым это необходимо. Обычно это делается в вашей входной точке интерфейса, которая делегирует процедуру, например, ClassPathXmlApplicationContext
для настройки spring. Образец может быть
public class SpringContextLoader {
private static ApplicationContext ctx = null;
public static void init() {
if (ctx == null) {
ctx = ClassPathXmlApplicationContext("classpath:/applicatonContext.xml");
}
}
}
Как мне управлять потоком мониторинга файловой системы? Является ли хорошим дизайном ожидать, что программа создаст основной класс библиотеки и инициирует вызов или что-то в этом роде?
В этом случае вы, вероятно, будете предоставлять поток не-демона, например поток, который должен быть завершен вручную, чтобы приложение могло выйти из него чисто. Следовательно, вы должны предоставить механизмы start
и stop
. В вашем случае их, вероятно, лучше называть registerEventListener
и unregisterAllEventListener
(поскольку я предполагаю, что вы хотите передать события файловой системы клиенту...). Другой альтернативой может быть использование quartz
планирования с помощью spring.
Ответ 2
Как инициализировать библиотечный контекст? Я не могу предположить, что пользователи библиотеки также будут использовать Spring, но я могу распространять Springс библиотекой.
Я пишу библиотеку, используя контекст Spring, и я сделал что-то подобное, предполагая, что ваша библиотека называется FooLib, имеет две службы с именем FooService и BarService и класс SpringContext, который настраивает ваш контекст Spring через java config:
public final class FooLib {
private static ApplicationContext applicationContext;
private FooLib() {
}
public static FooService getFooService() {
return getApplicationContext().getBean(FooService.class);
}
public static BarService getBarService() {
return getApplicationContext().getBean(BarService.class);
}
private static ApplicationContext getApplicationContext() {
if (applicationContext == null) {
applicationContext = new AnnotationConfigApplicationContext(SpringContext.class);
}
return applicationContext;
}
}
Тогда клиент может использовать BarService
следующим образом:
BarService barService = FooLib.getBarService();
Как мне управлять потоком мониторинга файловой системы? Хороший дизайн ожидайте, что программа создаст основной класс библиотеки и вызвать init или что-то в этом роде?
Вы можете запустить свою подсистему мониторинга статически в контексте Spring внутри класса SpringContext, например.
@Configuration
@ComponentScan(basePackages = "com.yourgroupid.foolib")
public class SpringContext {
@Bean
public MonitoringSystem monitoringSystem() {
MonitoringSystem monitoringSystem = new MonitoringSystem();
monitoringSystem.start();
return monitoringSystem;
}
}
Этого должно быть достаточно, потому что Spring по умолчанию создает свой beans.
Приветствия
Ответ 3
Как инициализировать библиотечный контекст? Я не могу предположить, что пользователи библиотеки также будут использовать Spring, но я могу распространять Spring с помощью библиотеки.
Вы можете использовать PropertyPlaceholderConfigurer
для чтения настроек конфигурации из (возможно, внешнего) файла свойств, который может быть отредактирован пользователями. Таким образом, пользователи не подвергаются деталям Spring, даже не в файлах конфигурации XML.
Как мне управлять потоком мониторинга файловой системы? Является ли хорошим дизайном ожидать, что программа создаст основной класс библиотеки и инициирует вызов или что-то в этом роде?
Я рекомендую использовать инфраструктуру Java concurrency, в частности ScheduledExecutorService
, чтобы запускать задачи (задачи) мониторинга через определенные промежутки времени. Тем не менее, вы можете скрыть эту деталь реализации от пользователей вашей библиотеки, только разоблачив некоторый метод init, чтобы пройти в нужный интервал таймера.
Ответ 4
Насколько я знаю, невозможно настроить вашу библиотеку для автоматического запуска потока, вы должны определить класс как отправную точку. Используя Maven, вы можете создать исполняемую банку:
http://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html
В вашем основном классе простое использование:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:myspring-context.xml");
context.registerShutdownHook();
Для потоков вы можете попробовать либо реализовать интерфейс runnable, либо инициализировать bean, который запускает потоки с помощью spring исполнителей задач. Более элегантное решение, которое я могу предложить, создает поток в качестве pojo, а затем с помощью планировщика задач spring, как показано ниже:
<bean id="threadPojo" class="com.mydomain.ThreadPojo">
</bean>
<task:scheduled-tasks scheduler="mydomainTaskScheduler">
<task:scheduled ref="threadPojo" method="process" fixed-delay="${delay-pool}"/>
</task:scheduled-tasks>
<task:scheduler id="mydomainTaskScheduler" pool-size="${my-pool-size}" />
Я надеюсь, что это будет полезно.