Часть, которую вам не хватает с инверсией управления, состоит в том, что прикладной уровень не вызывает конструктор напрямую. Он использует фабрику (контейнер IoC) для заполнения параметра конструктора.
Какой бы инструмент вы ни использовали, guice / spring / picocontainer / singleton-factory, код вашего приложения должен выглядеть примерно так:
@Controller
class MyController {
@Resource // Some container knows about this annotation and wires you in
MyBusinessLogic myBusinessLogic;
@RequestMethod("/foo/bar.*")
public MyWebResponse doService(Response resp, long id, String val) {
boolean worked = myBusinessLogic.manipulatevalue(id, val);
return new MyWebResponse(worked);
}
}
Обратите внимание, что myBusinessLogic может быть зарегистрирован несколькими способами - java's @Resource, MyBusinessLogicFactory.getMyBusinessLogic (), guice.get (MyBusinessLogic.class) и т. Д.
Решение для бедняков было бы:
package foo;
class MyBusinessLogicFactory {
static volatile MyBusinessLogic instance; // package-scoped so unit tests can override
public static MyBusinessLogic getInstance() {
if (instance == null) {
synchronized(MyBusinessLogicFactory.class) {
instance = new MyBusinessLogic(MyDatabaseLayerFactory.getInstance());
}
}
return instance;
}
}
// repeat with MyDatabaseLayerFactory
Обратите внимание, что приведенная выше модель синглтона крайне не рекомендуется, так как она не имеет смысла. Вы МОЖЕТЕ обернуть вышеупомянутое в контекст - успокаиваясь как
class Context {
Map<Class,Object> class2Instance = new ConcurrentHashMap<>();
public <T> T getInstance(Class<T> clazz) {
Object o = class2Instance.get(clazz);
if (o == null) {
synchronized(this) {
o = class2Instance.get(clazz);
if (o != null) return (T)o;
o = transitivelyLoadInstance(clazz); // details not shown
for (Class c : loadClassTree(clazz)) { // details not shown
class2Instance.put(c, o);
}
}
}
return (T)o;
}
...
}
Но в этот момент пикоконтейнер, обтекатель и пружина могут гораздо лучше решить все сложности вышеуказанного СООО.
Кроме того, такие вещи, как spring, использующие аннотации java 6, означают, что вы можете делать что-то кроме внедрения в конструктор, что ОЧЕНЬ полезно, если у вас есть несколько элементов конфигурации одного базового типа данных (например, строки).