Я работаю над полуразмерным приложением, использующим Spring 3, и сталкиваюсь с проблемами производительности, когда в него одновременно бросают сотни пользователей.Я использую несколько bean-объектов в области запроса, используя прокси Spring AOP, и я вижу, что каждый раз, когда я вызываю какой-либо метод для одного из этих bean-компонентов, вызывается перехватчик CGLIB, который затем вызывает AbstractBeanFactory.getBean (), который вызывает add () дляСинхронизированный набор существующих бинов Spring.Поскольку метод add () синхронизирован, он эффективно блокирует сервер, когда к нему обращаются тысячи вызовов, ожидающих добавления в тот же список.
Есть ли способ обойти это, используя bean-объекты области запроса?Я прочитал в документации Spring, что CGLIB не используется, если бин реализует какой-либо интерфейс (http://static.springsource.org/spring/docs/2.0.0/reference/aop.html#d0e9015), но все бины области моего запроса реализуют один (фактически один), и это все еще происходит. И мне определенно нужно, чтобы бины былиобласть действия запроса, потому что некоторые из их полей вычисляются в одной части приложения для конкретного запроса, а затем я использую SpEL, чтобы получить их значение в другой части приложения во время того же запроса. Я думаю, что если бы я сделал область действия прототипа bean-компонентов,У меня был бы свежий объект, когда я использовал SpEL, чтобы получить их во второй раз.
Вот пример кода, который иллюстрирует мою проблему. Смотрите последние две строки для комментариев, описывающих, где именно у меня возникают проблемы.
<!-- Spring config -->
<bean name="someBean" class="some.custom.class.SomeClass" scope="request">
<property name="property1" value="value1"/>
<property name="property2" value="value2"/>
<aop:scoped-proxy/>
</bean>
<bean name="executingClass" class="some.other.custom.class.ExecutingClass" scope="singleton">
<property name="myBean" ref="someBean" />
</bean>
public Interface SomeInterface {
public String getProperty1();
public void setProperty1(String property);
public String getProperty2();
public void setProperty2(String property);
}
public class SomeClass implements SomeInterface {
private String property1;
private String property2;
public String getProperty1() { return propery1; }
public void setProperty1(String property) { property1=property;}
public String getProperty2() { return propery2; }
public void setProperty2(String property) { property2=property;}
}
public class ExecutingClass {
private SomeInterface myBean;
public void execute() {
String property = myBean.getProperty1(); // CGLIB interceptor is invoked here, registering myBean as a bean
String otherProperty = myBean.getProperty2(); // CGLIB interceptor is invoked here too! Seems like this is unnecessary. And it's killing my app.
}
}
Мои идеи состоят в следующем:
- Могу ли я сделать запрос Spring Bean ограниченным, не проксируя каждый вызов метода, сделанный в bean? И без маркировкикаждый метод в качестве «окончательного»?
или ...
- Могу ли я переопределить фабрику бинов Spring в im?дополнить кеш Бина, который будет проверять, кэшируется ли бин перед вызовом AbstractBeanFactory.getBean ()?И если да, то где я могу настроить Spring для использования моей фабрики пользовательских компонентов?