2017-01-23 2 views
7

Мы столкнулись с проблемой многопоточности, когда разработчик ввел изменчивость в компонент Spring. Что-то вроде этого:Убедитесь, что пружинный компонент не имеет состояния

@Component //singleton 
public class MyComponent { 
... 
private String intermediateResults; 
public String businessMethod() { 
... fills in intermediateResults; 
} 

public String thisGetterShouldNotBeHere() { 
    return intermediateResults; 
} 
} 

, который привел к ошибке с многопоточностью - полевые intermediateResults обращались из разных потоков.

Есть ли способ предотвратить добавление состояния к Spring Singleton, например. каким-то статическим анализатором? Плагины SonarQube? Плагины Eclipse? Спасибо за предложения.

+0

http://stackoverflow.com/questions/777849/proper-usage-of-synchronized-singleton – joc

+0

Только один вопрос: не так ли? 'businessMethod()' делает класс изменчивым, а не Getter? –

+0

Конечно, businessMethod сделал его изменчивым. – leokom

ответ

2

Google, MutabilityDetector кажется способным сделать именно то, что вам нужно:

Изменчивость детектор предназначен для анализа классов Java и сообщать о том неизменны экземпляры данного класса. Его можно использовать:

  • В модульном тесте с утверждением типа assertImmutable (MyClass.class). Является ли ваш класс действительно неизменным? А что после этого изменения вы только что сделали?
  • Как плагин FindBugs. Те классы, которые вы комментировали с помощью @Immutable, на самом деле? Во время выполнения. Требуется ли для вашего API обязательные объекты? Из командной строки. Вы хотите быстро запустить Mutability Detector на всей кодовой базе?

я все равно советую добавить четкий договор о том, что класс должен быть неизменен либо через javadoc или через @Immutable аннотацию на самом классе, чтобы позволить (чувственные) разработчикам сохранить реквизиты класса. (Если детектор Google не смог обнаружить определенные типы неизменяемости, например: Are String, Date really immutable?)

+1

Кажется приятным инструментом. Попробует попробовать – Andres

+0

@Andres. Действительно, попробуйте проверить класс, который принимает коллекцию из конструктора, и устанавливает его конечное состояние с помощью Collection.unmodifiableCollection (...). Вы будете удивлены результатом :) – snovelli

+1

Это отличный инструмент, спасибо большое, @snovelli! – leokom

1

Вы могли бы реализовать свои собственные правила с любым статическим анализатором (как FindBugs, PMD и Checkstyle), чтобы проверить, что ваш класс:

  • позволяет только конечные свойства
  • Расширяет данный класс
  • является окончательным
  • Использует инъекции зависимостей конструктора

Однако, насколько я знаю, нет никакого инструмента specif для этого настроена из коробки.

В качестве альтернативы вы можете создать аннотацию @Immutable и выполнить там проверки.

+0

Многие приложения Spring используют инъекцию зависимостей через сеттер.В этом случае «final» не является вариантом. Не уверен в том, что вы будете заполнять окончательные поля - есть ли у вас какой-либо опыт? –

+3

Вам нужно будет использовать инъекцию зависимости конструктора, если вы хотите обеспечить неизменность. – Andres

+0

Используйте инъекцию зависимости конструктора. Решает не только этот случай, но и имеет ряд преимуществ. См. Https://spring.io/blog/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/ – borjab

Смежные вопросы