Наверное если мы делаем динамический прокси, было бы логичнее использовать аргументы хэндлера а не завязываться на глобальный объект. Так например CGLib это будет вот так
Да нет там никаких специальных образов. Есть два разных подхода (несмотря на то, что в обоих случаях используется CGLib).
Когда речь идет об аспектах, инстанс класса бизнес-логики создается в любом случае. Если методы данного класса подпадают под определения среза, то дополнительно создается прокси-объект. Именно этот прокси-объект регестрируется в контейнере в качестве бина. При этом он содержит ссылку на созданный инстанс бизнес-логики.
Если класс помечен аннотацией @Configuration то создается только инстанс класса наследника от него (т.е. никакого прокси нет и впомине).
Тут все по-настоящему, CGLib обертка не прикидывается, что уважает ООП.
Или я неправильно понял, что имелось ввиду, или как раз наоборот. С помощью CGLib создается класс наследник и дальше все как положено: наследование, полиморфизм…
Т.е. Спринг на самом деле не порождает бинов класса Cfg. Вместо этого создается класс наследник и уже от этого класса будет создан инстанс. В этом классе переопределяются все методы помеченные аннотацией Bean. После чего любое обращение к такому методу приведет к тому что будяет отрабатывать код а-ля context.getBean(). Обращение же к методам которые мы видим у класса конфигурации будут только тогда, когда действительно необходимо инстанциирование бина (определенного данным методом).
Что бы было проще отвечать пронумерую случаи в том порядке, в каком они были у вас приведены.
1) Здесь вот совсем не вижу причин для использования Propagation.REQUIRES_NEW. просто в цикле вызываем метод посчитатьЗаОдинМесяц() над котороым стоит Propagation.REQUIRED (ну или никакой propagation вообще не указываем, поскольку это дефолтный). Метод закончился, траннзакция комитнулась. Следующий вызов — новая транзакция.
2) Этот пример, если я его правильно понял, похож на тот, что выше привел nemavasi. Можно конечно спорить стоит ли вводить сервис агрегатор или просто воспользоваться возможностью Propagation.REQUIRES_NEW, но мое мнение такое. Как я писал выше, есть два сервиса: бизнес логики и логер. Оба над методами имеют @Transactional (с default propagation). И есть третий сервис (агрегатор), нетранзакционный. Он вызывает метод бизнес логики, тот в свою очередь (выполнив своючасть работы) вызывает логер. Если они нормально отрабатывают, то в одной транзакции завершают свою работу. Если они падают (неважно кто виноват, бизнес или логи) то агрегатор по try catch ловит этот случай и уже сам пытается воспользоваться сервисом логов.
3) Тут я не уверен, что понял пример. Выглядит так, что эти действия в принципе должны были выполняться в одной транзакции.
Хороший пример. Но я бы все-таки рекомендовал подходить к нему вот так. Есть два сервиса: 1) тот который должен выполнить нашу бизнес-логику и 2) логгер, который позволяет независимо от результатов первого сохранять информацию. И есть код который собственно и использует эти сервисы. Именно в этом коде мы и стартуем методы первого сервиса, и, в случае неудачи, по try catch вызывать методы второго.
Когда речь идет об аспектах, инстанс класса бизнес-логики создается в любом случае. Если методы данного класса подпадают под определения среза, то дополнительно создается прокси-объект. Именно этот прокси-объект регестрируется в контейнере в качестве бина. При этом он содержит ссылку на созданный инстанс бизнес-логики.
Если класс помечен аннотацией @Configuration то создается только инстанс класса наследника от него (т.е. никакого прокси нет и впомине).
Или я неправильно понял, что имелось ввиду, или как раз наоборот. С помощью CGLib создается класс наследник и дальше все как положено: наследование, полиморфизм…
Т.е. Спринг на самом деле не порождает бинов класса Cfg. Вместо этого создается класс наследник и уже от этого класса будет создан инстанс. В этом классе переопределяются все методы помеченные аннотацией Bean. После чего любое обращение к такому методу приведет к тому что будяет отрабатывать код а-ля context.getBean(). Обращение же к методам которые мы видим у класса конфигурации будут только тогда, когда действительно необходимо инстанциирование бина (определенного данным методом).
с этим полностью согласен
1) Здесь вот совсем не вижу причин для использования Propagation.REQUIRES_NEW. просто в цикле вызываем метод
посчитатьЗаОдинМесяц()
над котороым стоит Propagation.REQUIRED (ну или никакой propagation вообще не указываем, поскольку это дефолтный). Метод закончился, траннзакция комитнулась. Следующий вызов — новая транзакция.2) Этот пример, если я его правильно понял, похож на тот, что выше привел nemavasi. Можно конечно спорить стоит ли вводить сервис агрегатор или просто воспользоваться возможностью Propagation.REQUIRES_NEW, но мое мнение такое. Как я писал выше, есть два сервиса: бизнес логики и логер. Оба над методами имеют
@Transactional
(с default propagation). И есть третий сервис (агрегатор), нетранзакционный. Он вызывает метод бизнес логики, тот в свою очередь (выполнив своючасть работы) вызывает логер. Если они нормально отрабатывают, то в одной транзакции завершают свою работу. Если они падают (неважно кто виноват, бизнес или логи) то агрегатор по try catch ловит этот случай и уже сам пытается воспользоваться сервисом логов.3) Тут я не уверен, что понял пример. Выглядит так, что эти действия в принципе должны были выполняться в одной транзакции.