То, что вы описали, частично возможно. Вы можете исключить необходимость явной ссылки на скрытую сборку, но эта сборка по-прежнему будет втягиваться в компилируемое время и требуется во время выполнения.
Предположим, что вы определили эти классы:
// in assembly 1:
public class A
{
public virtual void Foo() { }
}
// and in assembly 2:
// requires explicit reference to assembly 1 to use
public class B : A
{
public override void Foo() { }
public A Value { get; set; }
public void Foo(A value) { }
}
// has implicit reference to assembly 1, but end user can ignore
public class C
{
private A Value { get; set; }
internal void Foo(A value) { }
protected internal A Bar() { return new A(); }
}
// usable at runtime even if assembly 1 is missing, as long as you don't call Foo()
public class D
{
public void Foo() { A blah = new A(); }
public void Bar() { }
}
Если конечный пользователь использует класс B, для них потребуется явная ссылка на сборку 1. Поскольку A является частью открытого интерфейса B, чтобы использовать B, вы должны знать об A. Существует 3 разных общедоступные ссылки на A, и любой из них потребует знания об A для использования B.
Однако класс C ссылается на A, но все ссылки являются частными / внутренними / локальными. Поскольку каждая ссылка на A скрыта снаружи, конечный пользователь не должен явно знать об ассемблере 1. Это все равно потребуется во время выполнения, но вам не нужно добавлять его в качестве ссылки, это косвенная ссылка .
И если конечный пользователь использует класс D, без использования B или C, сборка 1 будет загружаться только при вызове D.Foo (), которая имеет локальную переменную типа A. Вы можете фактически использовать D.Bar () свободно, даже если сборка 1 полностью отсутствует во время выполнения. Хотя если вы вызываете D.Foo (), а сборка 1 отсутствует, вы получите исключение.
Imho более чистая альтернатива передает экземпляр EJB
через Job
JobExecutionContext
При подготовке Job
final JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(MY_INTERFACE, myInterface);
final Job myJob =
JobBuilder.newJob(MyJob.class)
.setJobData(jobDataMap)
.build();
Внутри Job#execute
[ 1115]
final JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
final MyInterface myInterface = (MyInterface) jobDataMap.get(MY_INTERFACE);
Реализация Quartz Job
вообще не должна знать о контейнере JavaEE, в котором она работает. Это облегчит процесс обновления вашего кода / архитектуры в долгосрочной перспективе.
Кроме того, ваш Job
должен заботиться только о своей единственной обязанности, а не о получении необходимых зависимостей.
Думайте о JobDataMap
как о странном виде инъекции зависимости .