static class UserBox extends BeanBox {
Object create() {return new User("User2");}
}
public static class UserBox7 extends BeanBox {
{ setBeanClass(User.class);
setProperty("name", "User7");
}
}
public static class H8 extends UserBox {{setAsValue("User8");}}
public static void main(String[] args) {
User u1 = JBEANBOX.getInstance(User.class);
User u2 = JBEANBOX.getBean(UserBox.class);
User u3 = JBEANBOX.getBean(new BeanBox().injectConstruct(User.class, String.class, value("User3")));
User u4 = JBEANBOX.getBean(new BeanBox(User.class).injectValue("name", "User4" ));
User u5 = JBEANBOX
.getBean(new BeanBox(User.class).injectMethod("setName", String.class, value("User5")));
User u6 = JBEANBOX.getBean(new BeanBox().setBeanClass(User.class).setPostConstruct("init"));
User u7 = new UserBox7().getBean();
BeanBoxContext ctx = new BeanBoxContext();
Interceptor aop=new MethodInterceptor() {
public Object invoke(MethodInvocation invocation) throws Throwable {
invocation.getArguments()[0]="User9";
return invocation.proceed();
}
};
User u8 = ctx.rebind(String.class, "8").bind("8", H8.class)
.getBean(ctx.getBeanBox(User.class).addMethodAop(aop, "setName",String.class).injectField("name", autowired()));
System.out.println(u1.name); //Result: User1
System.out.println(u2.name); //Result: User2
System.out.println(u3.name); //Result: User3
System.out.println(u4.name); //Result: User4
System.out.println(u5.name); //Result: User5
System.out.println(u6.name); //Result: User6
System.out.println(u7.name); //Result: User7
System.out.println(u8.name); //Result: User8
u8.setName("");
System.out.println(u8.name); //Result: User9
ctx.close();
System.out.println(u8.name); //Result: User10
}
``` **Текст запроса написан на языке Java.**
**Перевод текста запроса:**
public static class OracleDataSourceBox extends MySqlDataSourceBox {//继承父类的username和password { injectValue("jdbcUrl", "jdbc:oracle:thin:@127.0.0.1:1521:XE"); injectValue("driverClassName", "oracle.jdbc.OracleDriver"); } }
public static class DataSourceBox extends OracleDataSourceBox { }
В любом месте программы можно вызвать JBEANBOX.getBean(DataSourceBox.class), чтобы получить источник данных, тип которого определяется конфигурационным файлом. В отличие от Spring с использованием методов, конфигурация jBeanBox использует сам класс Java, поэтому конфигурацию можно записать в любом месте без необходимости добавления каких-либо аннотаций, поскольку конфигурация представляет собой обычный класс Java.
### Детальное описание конфигурации jBeanBox в стиле Java
Приведённый выше код является лишь общим примером конфигурации jBeanBox в стиле Java. Ниже представлено подробное описание метода конфигурации Java:
* setAsValue(Object) — превращает текущий BeanBox в константное значение, эквивалентно setTarget(Obj) + setPureVale(true).
* setPrototype(boolean) — если параметр равен true, это означает, что он не является синглтоном, и работает противоположно методу setSingleton.
* injectConstruct(Class<?>, Object...) — устанавливает конструктор инъекции, параметры — это класс, типы параметров конструктора и сами параметры.
* injectMethod(String, Object...) — устанавливает инъекцию для определённого метода, параметры — имя метода, типы параметров и сами параметры.
* addMethodAop(Object, Method) — добавляет AOP к определённому методу, параметры — класс или экземпляр AOP, метод.
* addMethodAop(Object, String, Class<?>...) — добавляет AOP к определённому методу, параметры — класс или экземпляр AOP, имя метода, типы параметров.
* addBeanAop(Object, String) — добавляет AOP ко всему Bean, параметры — класс или экземпляр AOP, правило метода (например, «setUser*»).
* setPostConstruct(String) — устанавливает метод PostConstruct, эффект аналогичен аннотации @PostConstruct.
* setPreDestroy(String) — устанавливает метод PreDestroy, эффект аналогичен аннотации @PreDestroy.
* injectField(String, BeanBox) — внедряет поле, параметры — имя поля, экземпляр BeanBox, его эквивалентная аннотация — @INJECT.
* setProperty(String, Object) — аналогично методу injectValue.
* injectValue(String, Object) — внедряет поле, параметры — имя поля, объект экземпляра, можно сравнить с аннотацией @VALUE.
* setTarget(Object) — определяет цель текущего Bean, кроме того, при bind («7», User.class) setTarget («7») эквивалентен setTarget (User.class).
* setPureValue(boolean) — указывает, что target больше не является целью, а возвращается как чистое значение, строка «7» будет возвращена как строка «7».
* setBeanClass(Class<?>) — устанавливает конечный целевой класс текущего BeanBox, вся конфигурация основана на этом классе.
* setSingleton(Boolean) — если параметр равен true, то это синглтон, работает противоположно setPrototype.
* setConstructor(Constructor<?>) — устанавливает конструктор.
* setConstructorParams(BeanBox[]) — устанавливает параметры конструктора, используется вместе с предыдущим методом.
* setPostConstruct(Method) — устанавливает метод PostConstruct, эффект аналогичен аннотации @PostConstruct.
* setPreDestroy(Method) — устанавливает метод PreDestroy, эффект аналогичен аннотации @PreDestroy.
Для BeanBox есть два специальных метода create и config. Пример использования:
public static class DemoBox extends BeanBox {
public Object create() {
return new Book();
}
public void config(Object o) {
(Book)o.setTitle("Foo");
}
}
Пример показывает, что созданный Bean в DemoBox генерируется методом create, а метод config используется для изменения.
Кроме того, следует отметить, что методы create и config могут принимать параметр BeanBoxContext, который используется в особых случаях, когда требуется контекст.
### AOP (аспектно-ориентированное программирование) в jBeanBox
jBeanBox поддерживает большинство своих функций через конфигурацию Java или аннотации. Аналогично, он также поддерживает AOP двумя способами:
#### Конфигурация AOP в стиле Java
* someBeanBox.addMethodAop(Object, String, Class<?>...) — добавляет AOP к определённому методу, параметры — класс или экземпляр AOP, имя метода, типы параметров.
* someBeanBox.addBeanAop(Object, String) — добавляет AOP ко всему классу, параметры — класс или экземпляр AOP, правило метода (например, «setUser*|getName*»).
* someBeanBoxContext.addContextAop(Object, Object, String); — добавляет правило AOP ко всему контексту, параметры — класс или экземпляр AOP, класс или правило класса, имя метода.
Эти три метода соответствуют трём различным уровням правил AOP. Первый метод применяется только к методам, второй — ко всему классу, третий — ко всему контексту. Вот пример конфигурации AOP в Java:
public static class AopDemo1 { String name; String address; String email; //getter & setters... }
public static class MethodAOP implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { invocation.getArguments()[0] = "1"; return invocation.proceed(); } }
public static class BeanAOP implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { invocation.getArguments()[0] = "2"; return invocation.proceed(); } }
public static class ContextAOP implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { invocation.getArguments()[0] = "3"; return invocation.proceed(); } }
public static class AopDemo1Box extends BeanBox { { this.injectConstruct(AopDemo1.class, String.class, value("0")); this.addMethodAop(MethodAOP.class, "setName", String.class); this.addBeanAop(BeanAOP.class, "setAddr*"); } }
@Test public void aopTest1() { JBEANBOX.ctx().addContextAop(ContextAOP.class, AopDemo1.class, "setEm*"); AopDemo1
* Добавление AOP в текущий контекст: второй параметр — указанный класс (будет соответствовать всем классам, которые начинаются с указанного класса, например, если указан класс a.b.C, то также будет соответствовать a.b.CXX), третий параметр — правило нечёткого соответствия имени метода.
* getBeanBox(Class<?>) — получение экземпляра BeanBox для класса, например, класса с аннотациями. Этот метод можно использовать для получения экземпляра BeanBox и последующей модификации его конфигурации. Это пример использования фиксированной и динамической конфигурации вместе.
* setAllowAnnotation(boolean) — установка разрешения на чтение аннотаций в классе. Если установлено значение false, jBeanBox будет работать только с конфигурацией на чистом Java. По умолчанию true.
* setAllowSpringJsrAnnotation(boolean) — настройка разрешения на чтение части аннотаций JSR330/JSR250 и Spring для обеспечения совместимости. По умолчанию true.
* setValueTranslator(ValueTranslator) — определение способа разбора строки параметра в аннотации @VALUE, например, @VALUE("#user"). Система по умолчанию возвращает строку "#user". Если необходимо другое толкование, например, чтение значения из текста свойства, необходимо настроить экземпляр, реализующий интерфейс ValueTranslator.
### Производительность jBeanBox
Сравнение производительности jBeanBox с другими инструментами IOC (только функция DI-инъекции). Создано дерево экземпляров из 6 объектов. Видно, что скорость создания несинглтонов у jBeanBox медленнее, чем у Guice в два раза, и быстрее, чем у Spring примерно в 45 раз. Обычно инструменты IOC используются для синглтонов, так как они берутся из кэша, и их производительность примерно одинакова. Однако, если требуется частое создание несинглтонов, например, при каждом обращении создаётся новый объект страницы, Spring может стать узким местом.
Тестовая программа доступна по ссылке: [di-benchmark] (https://github.com/drinkjava2/di-benchmark).
Результаты тестов:
| | Время запуска контейнера DI и создания графа зависимостей 4999 раз | Время получения нового бина 500 000 раз | Время получения синглтона 5 000 000 раз |
| :-- |:--:| --:| --:|
| Vanilla | старт: 0 мс, получение: 0 мс | 31 мс | 47 мс |
| Guice | старт: 1046 мс, получение: 1560 мс | 1154 мс | 1950 мс |
| Feather | старт: 0 мс, получение: 109 мс | 624 мс | 624 мс |
| Dagger | старт: 46 мс, получение: 173 мс | 312 мс | 2746 мс |
| Genie | старт: 766 мс, получение: 247 мс | 609 мс | 327 мс |
| Pico | старт: 376 мс, получение: 217 мс | 4555 мс | 3385 мс |
| jBeanBoxNormal | старт: 79 мс, получение: 982 мс | 2075 мс | 188 мс |
| jBeanBoxTypeSafe | старт: 0 мс, получение: 998 мс | — | 187 мс |
| jBeanBoxAnnotation | старт: 0 мс, получение: 468 мс | — | 171 мс |
| SpringJavaConfiguration | старт: 51 831 мс, получение: 1834 мс | 92 149 мс | 1061 мс |
| SpringAnnotationScanned | старт: 70 712 мс, получение: 4155 мс | 95 504 мс | 1045 мс |
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )