click here(git@osc) чтобы получить английскую версию руководства.
Pure.IoC – это легковесный автоматический фреймворк внедрения зависимостей на основе классов и аннотаций.
Использует JDK 1.8
Рекомендовано использовать вместе с Spring
<dependency>
<groupId>net.cassite</groupId>
<artifactId>pure.ioc</artifactId>
<version>0.3.2</version>
</dependency>
Использует уже существующие логические связи вместо сложной конфигурации.
Обычно при написании Java используется фреймворк Spring для управления IoC. Spring основан на beanах, поэтому требуется отображение классов в beanы и описание зависимости между ними.
На самом деле, часто зависимости могут быть определены только по типу. Например,
class A{
...
public void setB(B b){ this.b = b; }
}
class B{
}
Очевидно, что A зависит от B, и A должен будет передать экземпляр B через метод setB. Это естественная логическая связь.
Типовая зависимость уже установлена во время написания кода, так что было бы полезно иметь инструмент, который помог бы автоматически выполнять такие "очевидные" зависимости. Поэтому был создан Pure.IoC
При проектировании Pure.IoC были учтены различные ситуации. Рассмотрим следующий пример:
@Singleton
@Wire
class Complex{
private ...
public Complex(){ ... }
@Default public Complex(AnotherClass obj){ ... }
public void setA(A a){ ... }
public void setB(B b){ ... }
public void setInterface(Interf1 interf){ ... }
public void setInterface(@Use(clazz=Impl2.class)Interf2 interf){ ... }
}
@Default(clazz=Impl1.class) interface Interf1{ ... }
Эти аннотации означают:
Аннотации могут быть бесконечными, но они не должны усложнять систему. В результате использована следующая архитектура:
AnnotationHandler + HandlerChain
AnnotationHandler делится на три типа,
Хэндлеры регистрируются в IOCController, где они обрабатываются в порядке регистрации. Реализация хэндлеров немного напоминает AOP, обычно вызывается chain.next().handle(...), затем принимаются решения на основе возвращаемого значения или выбрасываемых исключений. Подробнее см. документацию по интерфейсу handle каждого хэндлера.
Таким образом, можно легко расширять аннотации.
Циклические зависимости хотя и не очень распространены, но могут возникнуть. A -> B -> C -> A
Логически, один из A, B, C должен быть singleton, иначе создание объектов будет бесконечным циклом.
Кроме того, Spring требует, чтобы конструкторы не имели циклических зависимостей, иначе сборка невозможна.
Но Pure.IoC изящно решает проблему циклических зависимостей.
Поэтому даже если конструкторы содержат циклические зависимости, все равно можно успешно выполнить внедрение (все зависимости являются конструкторными).
Pure.IoC, будучи спроектированным для внедрения при конструировании, может быть использован без каких-либо дополнительных компонентов. Также он может работать вместе со Spring. Даже часть setter может быть внедрена через этот фреймворк, а другая часть — через Spring.
Прямое использование с Struts2 также возможно. Поскольку весь процесс внедрения полностью внутри класса, нет необходимости в специальной конфигурации объектного фабрикатора Struts2, как это требуется в случае Spring.
Рекомендуется использовать следующий подход:
extends AutoWire
Но иногда необходимо наследовать другой класс, тогда есть два способа решения проблемы:
@Wire class A { ... }
Класс, помеченный аннотацией @Wire, будет внедрен в любом случае, когда он проходит через Pure.IoC.
Для получения экземпляра можно использовать
AutoWire.get(A.class)
class A {
public A(){
AutoWire.wire(this);
}
}
В конструкторе передается ссылка на себя для внедрения.
На самом деле все входные точки в конечном итоге вызывают AutoWire.wire(Object)
Сначала используйте любой из трех вышеописанных методов для подключения к фреймворку.
Затем в точке входа программы вызовите
IOCController.autoRegister();
или зарегистрируйте каждый хэндлер вручную, например,
register(new DefaultConstructorFilter());
Если вы работаете в Java EE, вы можете использовать Listener для выполнения этой операции
Наконец, вызовите
IOCController.closeRegistering();
чтобы закрыть регистрацию хэндлеров. (этот шаг необязательный, просто для гарантии, что список хэндлеров не будет модифицироваться)
Если хэндлеры не зарегистрированы, но сборка началась, будут вызваны autoRegister()
и closeRegistering()
.
При отсутствии участия аннотаций поведение по умолчанию такое:
при внедрении setter, получается параметр типа и запрашивается экземпляр у IOCController, затем вызывается invoke setter.
При получении экземпляра, берется уникальный конструктор или конструктор без параметров.
Если конструктор имеет параметры, берутся экземпляры соответствующего типа.
Затем производится конструирование.
Если доступного внедрения нет, будет проведена проверка примитивных типов и массивов, и они будут инициализированы значением по умолчанию (0, false, array[length=0]).
Сессия существует в течение всего времени от начала сборки до её завершения. Почти каждый метод передаёт параметр сессии.
Например:
A зависит от B, B зависит от C и D. Где A и C наследуют AutoWire (явно вызывают AutoWire.wire(o)), а B и D используют аннотацию Wire.
Тогда ABD будут использовать одну сессию, а C — свою собственную.
Предоставлен класс Utils, содержащий некоторые общие операции и защищённые методы из IOCController. Если вам удобнее не наследовать IOCController, вы можете использовать методы из Utils для вызова этих защищённых методов.
Основная цель — упрощение работы с получением объектов из других объектных фабрик. Но не ограничивается этим.
Можно рассматривать его как упрощение расширения.
Он используется для одновременной обработки Type, Setter и Param, но принимает только массив строковых параметров.
Реализация интерфейса ScopeAware и аннотация @Wire приведут к тому, что метод будет вызван с текущим Scope в качестве параметра. На самом деле, можно просто записать setScope(Scope s) для выполнения внедрения.
С версии Yöntem 0.1.1 добавлена возможность использования AOP.
Чтобы активировать AOP, установите
@AOP({Weaver.class,...})
на классах с интерфейсами.
Когда такой класс будет внедрён Pure.IoC, или когда будет вызван
AOPController.weave(() -> экземпляр этого класса, Class.class)
будет получен прокси-объект.
class YourWeaver implements Weaver{
@Override
protected void doBefore(AOPPoint point) {
...
}
@Override
protected void doAfter(AOPPoint point) {
...
}
@Override
protected void doException(AOPPoint point) throws Throwable {
...
}
}
doBefore, doAfter, doException соответственно соответствуют Before, AfterReturn, AfterThrowing типам. Здесь это также является Around типом.
Также предоставлены BeforeWeaver, AfterWeaver, ExceptionWeaver.
Если вам нужны только определённые cut points, вы можете наследовать эти классы.
Если вам нужно использовать Introduction тип, это тоже довольно просто, достаточно реализовать нужные интерфейсы в вашем Weaving.
Используйте
@AOP({Weaver1.class, Weaver2.class, ...})
для вплетания
Если вы хотите использовать cglib, вы можете принудительно установить useCglib=true
@AOP(value={Weaver1.class, Weaver2.class, ...}, useCglib=true)
Процесс AOP следует следующим шагам
Этот класс содержит следующие публичные поля/методы
Реализация интерфейса TargetAware в Weaving приведёт к вызову метода с прокси объектом в качестве параметра после получения экземпляра Weaving.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )