lastaflute / lasta-di

DI Container for LastaFlute, forked from Seasar as Java8
Apache License 2.0
9 stars 1 forks source link

cool reading timing is varying by redefiner's addiitional container #45

Open jflute opened 1 month ago

jflute commented 1 month ago

// Japanese here

こちらの件より: Research, Fess's SearchEngineClient refers LoginAssist as getComponent() #44

redefinerが、追加のcontainerなどで LaContainerFactory@create() を呼んでいる。

だが、LaContainerFactory@create()は本来はroot containerを読み込むためのもののはず。
coolのときは、読み込みの最後でcoolのcontainerがincludeされるようになっているが、
途中でredefiner経由で呼ばれると、redefinerの追加的containerからincludeされることになる。

それで所属のcontainerが変わって、初期化タイミングが変わってしまっているのだと思われる。
このままでいいのか?coolのコンポーネントたちは最終的にどのcontainerの所属になるのか?

でも、問題は起きてないので良いのだが... 本来的には、richの初期化タイミングでquickが存在してしまっていることが想定外の挙動。

要検証: coolのコンポーネントたちの所属のcontainerはrootじゃなくて途中になるのかな?

jflute commented 1 month ago

一応、coolが先読み込みされても、コンポーネントはrootコンテナに登録されるっぽい:

public void test_demo() throws Exception { // MySQL
    LaContainer container = SingletonLaContainerFactory.getContainer();
    int componentDefSize = container.getComponentDefSize();
    for (int i = 0; i < componentDefSize; i++) {
        ComponentDef componentDef = container.getComponentDef(i);
        log(componentDef.getComponentName());
    }
}
2024-10-22 11:19:54,217 [main] INFO  (LastaToActionFilter@showBoot():106) - _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2024-10-22 11:19:54,218 [main] INFO  (LastaToActionFilter@showBoot():107) -  the system has been initialized:
2024-10-22 11:19:54,219 [main] INFO  (LastaToActionFilter@showBoot():108) - 
2024-10-22 11:19:54,219 [main] INFO  (LastaToActionFilter@showBoot():109) -   -> Fortress (Local Development)
2024-10-22 11:19:54,219 [main] INFO  (LastaToActionFilter@showBoot():110) - _/_/_/_/_/_/_/_/_/_/
2024-10-22 11:19:54,235 [main] INFO  (DBFluteSystem@unlock():242) - ...Unlocking the DBFlute system
2024-10-22 11:19:54,235 [main] INFO  (DBFluteSystem@setFinalTimeZoneProvider():218) - ...Setting finalTimeZoneProvider: FortressCurtainBeforeHook$1:{Asia/Tokyo}
2024-10-22 11:19:54,235 [main] INFO  (DBFluteSystem@lock():232) - ...Locking the DBFlute system
2024-10-22 11:19:54,236 [main] DEBUG (FortressCurtainBeforeHook@whiteboxtest_findLoginManager():103) - findLoginManager() when booting: opt:{org.docksidestage.app.web.base.login.FortressLoginAssist@70f02c32}
2024-10-22 11:19:54,294 [main] DEBUG (LaTransaction@begin():83) - Begin transaction: [FormatId=4360, GlobalId=1729563594293/0, BranchId=]
2024-10-22 11:19:54,296 [main] DEBUG (PlainTestCase@log():750) - onionarc_application_onionarcSeaAppService
2024-10-22 11:19:54,296 [main] DEBUG (PlainTestCase@log():750) - onionarc_domain_repository_onionarcSeaRepository
2024-10-22 11:19:54,296 [main] DEBUG (PlainTestCase@log():750) - onionarc_domain_service_onionarcSeaDomainService
2024-10-22 11:19:54,297 [main] DEBUG (PlainTestCase@log():750) - cleaneg_infrastructure_cleanegSeaInfraRepository
2024-10-22 11:19:54,297 [main] DEBUG (PlainTestCase@log():750) - rootAction
2024-10-22 11:19:54,298 [main] DEBUG (PlainTestCase@log():750) - lido_auth_lidoAuthAction
2024-10-22 11:19:54,298 [main] DEBUG (PlainTestCase@log():750) - lido_product_lidoProductDetailAction
...

CoolComponentAutoRegister@processClass()にて、明示的にrootコンテナに登録しているからのようだ。 初期化タイミングが早まっても登録される場所は現在のコンテナではなくrootになるので挙動はほぼ変わらないと。

container.getRoot().register(cd);
registeredClasses.add(cd.getComponentClass());
ComponentUtil.putRegisterLog(cd);
...

quickにrichへの依存がたくさんある場合は?

jflute commented 1 month ago

quickにrichへの依存がたくさんある場合は?

試しにRootActionにrichへのDIを追加しても初期化タイミングは変わらない。

@Resource
private AsyncManager asyncManager;
@Resource
private TimeManager timeManager;

この辺はDIの仕組みになるので、良い感じに解決されるのかな?

実際に、すでにTimeManagerとかActionクラスでたくさん使ってるけど問題ないわけで。

testでRootActionをDIして、TimeManagerを利用しても問題なし。 ログを見る限りは初期化タイミングは逆転してるけど問題なし。

@PostConstructでDIとgetCmponent()両方やっても問題なし。

@PostConstruct
public void init() {
    System.out.println("@@@1: " + timeManager.currentDate());
    System.out.println("@@@2: " + ContainerUtil.getComponent(TimeManager.class).currentDate());
}

でもPostConstructの呼ばれるタイミングが遅いな...と思ったら、そりゃそうか。 prototypeだから利用される時にnewされてPostConstructされるからか。

2024-10-22 11:31:06,647 [main] INFO  (LastaToActionFilter@showBoot():106) - _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2024-10-22 11:31:06,648 [main] INFO  (LastaToActionFilter@showBoot():107) -  the system has been initialized:
2024-10-22 11:31:06,648 [main] INFO  (LastaToActionFilter@showBoot():108) - 
2024-10-22 11:31:06,648 [main] INFO  (LastaToActionFilter@showBoot():109) -   -> Fortress (Local Development)
2024-10-22 11:31:06,648 [main] INFO  (LastaToActionFilter@showBoot():110) - _/_/_/_/_/_/_/_/_/_/
2024-10-22 11:31:06,658 [main] INFO  (DBFluteSystem@unlock():242) - ...Unlocking the DBFlute system
2024-10-22 11:31:06,659 [main] INFO  (DBFluteSystem@setFinalTimeZoneProvider():218) - ...Setting finalTimeZoneProvider: FortressCurtainBeforeHook$1:{Asia/Tokyo}
2024-10-22 11:31:06,659 [main] INFO  (DBFluteSystem@lock():232) - ...Locking the DBFlute system
2024-10-22 11:31:06,659 [main] DEBUG (FortressCurtainBeforeHook@whiteboxtest_findLoginManager():103) - findLoginManager() when booting: opt:{org.docksidestage.app.web.base.login.FortressLoginAssist@70f02c32}
@@@1: 2024-10-22
@@@2: 2024-10-22
2024-10-22 11:31:06,693 [main] DEBUG (LaTransaction@begin():83) - Begin transaction: [FormatId=4360, GlobalId=1729564266692/0, BranchId=]
...
jflute commented 1 month ago

Coolのコンポーネントは、初期化タイミングがズレてもrootコンテナに登録される。 だからこそ、基本的な挙動が変わらないってことか。

CoolComponentAutoRegister:

    public void processClass(final String packageName, final String shortClassName) {
        if (shortClassName.indexOf('$') != -1) {
            return;
        }
        final String className = LdiClassUtil.concatName(packageName, shortClassName);
        if (!namingConvention.isTargetClassName(className)) {
            return;
        }
        final Class<?> clazz = LdiClassUtil.forName(className);
        if (namingConvention.isSkipClass(clazz)) {
            return;
        }
        if (container.getRoot().hasComponentDef(clazz)) {
            if (clazz.isInterface() || LdiModifierUtil.isAbstract(clazz)) {
                return;
            }
            final ComponentDef cd = container.getRoot().getComponentDef(clazz);
            if (clazz == cd.getComponentClass()) {
                return;
            }
        }
        final ComponentDef cd = createComponentDef(clazz);
        if (cd == null) {
            return;
        }
        if (registeredClasses.contains(cd.getComponentClass())) {
            return;
        }

        // cool components are always registered to root container
        container.getRoot().register(cd);

        registeredClasses.add(cd.getComponentClass());
        ComponentUtil.putRegisterLog(cd);
    }