Что такое Maven Snapshot и зачем нам это нужно?
===============================================

Я немного смущен о значении моментального снимка Maven и почему мы строим его?

 

Версия моментального снимка в Maven - это тот, который не был выпущен.

Идея заключается в том, что завершена  **до** версия `1.0` (или любая другая версия), существует `1.0-SNAPSHOT`. Эта версия может стать `1.0`. Это в основном "`1.0` в разработке". Это может быть близко к реальной версии `1.0` или довольно далеко (сразу после выпуска `0.9`, например).

Разница между "реальной" версией и версией моментального снимка заключается в том, что моментальные снимки могут получать обновления. Это означает, что загрузка `1.0-SNAPSHOT` сегодня может дать другой файл, чем загрузка его вчера или завтра.

Обычно зависимости от моментального снимка должны быть  **только** во время разработки, и никакая выпущенная версия (т.е. без моментального снимка) должна иметь зависимость от версии моментального снимка.

 

Три других ответа дают вам хорошее представление о том, что такое версия `-SNAPSHOT`. Я просто хотел добавить некоторую информацию о поведении Maven, когда он находит зависимость `SNAPSHOT`.

При создании приложения Maven будет искать зависимости в **локальном** репозитории. Если стабильная версия там не найдена, она будет искать удаленные репозитории (определенные в `settings.xml` или `pom.xml`), чтобы найти эту зависимость. Затем он скопирует его в локальный репозиторий, чтобы сделать его доступным для следующих сборок.

Например, библиотека `foo-1.0.jar` считается **стабильной** версией, и, если Maven найдет ее в локальном хранилище, она будет использовать ее для текущей сборки.

Теперь, если вам нужна библиотека `foo-1.0-SNAPSHOT.jar`, Maven будет знать, что эта версия нестабильна и может быть изменена. Поэтому Maven будет пытаться найти более новую версию в удаленных репозиториях, даже если версия этой библиотеки найдена в локальном репозитории. Однако эта проверка производится только один раз в день. Это означает, что если у вас есть `foo-1.0-20110506.110000-1.jar` (то есть эта библиотека была сгенерирована 2011/05/06 в 11:00:00) в вашем локальном хранилище, и если вы снова запустите сборку Maven в тот же день, Maven будет **не** проверять репозитории на наличие более новой версии.

Maven предоставляет вам способ изменить эту политику обновления в определении вашего хранилища:

```
<repository>
    <id>foo-repository</id>
    <url>...</url>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>XXX</updatePolicy>
    </snapshots>
</repository>

```

где `XXX` может быть:

* **всегда**: Maven будет проверять наличие новой версии при каждой сборке;
* **ежедневно**, значение по умолчанию;
* **интервал: XXX**: интервал в минутах (XXX)
* **никогда**: Maven никогда не попытается получить другую версию. Это будет сделано, только если он не существует локально. При конфигурации версия `SNAPSHOT` будет обрабатываться как стабильные библиотеки.

(модель файла settings.xml можно найти здесь [)](http://maven.apache.org/ref/2.2.1/maven-settings/settings.html)



 Термин "SNAPSHOT" означает, что сборка представляет собой снимок вашего кода в определенный момент времени.

  Обычно это означает, что эта версия все еще находится в стадии разработки.

  Когда код будет готов и пришло время его выпустить, вы захотите изменить версию, указанную в POM. Тогда вместо "SNAPSHOT" вы бы использовали метку типа "1.0".

  Для некоторой помощи с версионированием, проверьте [Спецификацию Семантического Версионирования](http://semver.org).

 

 "Релиз" - это финальная сборка для версии, которая не изменяется.

  "Снимок" - это сборка, которая может быть заменена другой сборкой с таким же именем. Это означает, что сборка может измениться в любое время и все еще находится в активной разработке.

  У вас есть разные артефакты для разных сборок на основе одного и того же кода. Например, у вас может быть один с отладкой и один без. Один для Java 5.0 и один для Java 6. Как правило, проще иметь одну сборку, которая делает все, что вам нужно. ;)

 

 Версия Maven может содержать строковый литерал "SNAPSHOT", чтобы показать, что проект в настоящее время находится в активной разработке.

  Например, если ваш проект имеет версию "1.0-SNAPSHOT", и вы развертываете эти артефакты проектов в репозиторий Maven, Maven расширит эту версию до "1.0-20080207-230803-1", если вы планируете развернуть выпуск на 11: 08 PM 7 февраля 2008 UTC. Другими словами, при развертывании моментального снимка вы не выпускаете программный компонент; вы выпускаете моментальный снимок компонента в определенное время.

  Поэтому в основном проекты с моментальным снимком используются для активных проектов. Если ваш проект зависит от программного компонента, который находится в активной разработке, вы можете зависеть от выпуска моментального снимка, и Maven будет периодически пытаться загрузить последний снимок из репозитория при запуске сборки. Аналогично, если следующий выпуск вашей системы будет иметь версию "1.8", ваш проект будет иметь версию "1.8-SNAPSHOT", пока он не будет официально выпущен.

  Например, следующая зависимость всегда будет загружать последние 1,8 разработки JAR весны:

 
```
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>1.8-SNAPSHOT"</version>
    </dependency>

```
  [специалист](https://books.google.de/books?id=cBvZ4s72Z0gC&printsec=frontcover&dq=Maven:%20The%20Definitive%20Guide:%20The%20Definitive%20Guide%20pdf&hl=en&sa=X&ved=0ahUKEwjd89yxsYbVAhUSb5oKHWQ1ANkQ6AEIIjAA#v=onepage&q=Maven%3A%20The%20Definitive%20Guide%3A%20The%20Definitive%20Guide%20pdf&f=false%23v=onepage&q=Maven:)

  Пример процесса освобождения maven

  [![enter image description here]()](/img/1a230216ed2a268c9409e83b5c119d0f.png)

 

Я хотел бы остановиться на терминологии. Другие ответы дали хорошие объяснения о том, что такое "снимок" версии в контексте Maven. Но следует ли из этого, что версию без снимка следует называть версией "релиза"?

Существует некоторая напряженность между идеей семантического управления версиями "релизной" версии, которая, по-видимому, представляет собой любую версию, у которой нет спецификатора, такого как `-SNAPSHOT`, но также нет спецификатора, такого как `-beta.4`; и идея Maven о "релизной" версии, которая, по-видимому, включает только отсутствие `-SNAPSHOT`.

Другими словами, существует семантическая двусмысленность того, означает ли "выпуск" "мы можем выпустить его для Maven Central" или "программное обеспечение находится в окончательном выпуске для общественности". Мы могли бы считать `-beta.4` "релизной" версией, если мы выпустим ее для публики, но это не "финальная версия". [Семантическое управление версиями](https://semver.org/#spec-item-9) ясно говорит, что что-то вроде `-beta.4` является "предварительной версией", поэтому не имеет смысла называть ее "релизной" версией, даже без `-SNAPSHOT`. На самом деле, по определению, даже `-rc.5` является кандидатом на релиз, а не на настоящий релиз, хотя мы можем разрешить публичный доступ для тестирования.

Таким образом, несмотря на это, по моему мнению, более уместно называть "релизную" версию, в которой вообще нет спецификатора, даже `-beta.4`. Возможно, лучшим названием для версии без снимков в Maven будет "стабильная" версия (вдохновленная [другим ответом](/questions/1730/what-exactly-is-a-maven-snapshot-and-why-do-we-need-it/21209#21209)). Таким образом, мы бы получили:

* `1.2.3-beta.4-SNAPSHOT`: снимок версии предварительной версии.
* `1.2.3-SNAPSHOT`: снимок продакшен версии.
* `1.2.3-beta.4`: стабильная версия предварительной версии.
* `1.2.3`: продакшен версия (очевидно, это стабильная версия без снимков).



Вот как выглядит снимок для репозитория, и в этом случае он не включен, что означает, что репозиторий, упомянутый здесь, является стабильным, и нет необходимости в обновлениях.

```
<project>
    ...
    <repositories>
        <repository>
            <id>lds-main</id>
            <name>LDS Main Repo</name>
            <url>http://code.lds.org/nexus/content/groups/main-repo</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

```

Другой случай:

```
<snapshots>
        <enabled>true</enabled>
</snapshots>

```

 что означает, что Maven будет искать обновления для этого репозитория. Вы также можете указать интервал для обновлений с тегом.

 

 обычно в maven у нас есть два типа сборок 1) сборки снимков 2) выпуск сборок

 1. сборки снимка: SNAPSHOT - это специальная версия, которая указывает текущую копию развертывания, отличную от обычной версии, maven проверяет версию для каждой сборки в удаленном репозитории, поэтому сборки снимка представляют собой не что иное, как сборки разработки.
2. Выпуск сборки: выпуск означает удаление SNAPSHOT в версии для сборки, это обычные версии сборки.

 

 просто снимок означает, что это не стабильная версия.

  когда версия включает снимок, например 1.0.0 -SNAPSHOT, это означает, что это нестабильная версия, и ищите удаленный репозиторий для разрешения зависимостей

 

 Понимание контекста SDLC поможет понять разницу между снимком и выпуском. В процессе разработки все разработчики вносят свои функции в базовую ветку. В какой-то момент ведущий думает, что накопилось достаточно функций, и он отключит ветку релиза от базовой ветки. Любые сборки до этого момента времени являются снимками. Посты постов на данный момент являются релизами. Следует отметить, что сборки выпуска могут также измениться перед запуском в производство, если в ходе тестирования выпуска будут обнаружены дефекты.

 

 Снимок просто означает, что в зависимости от вашей конфигурации Maven будет проверять последние изменения по специальной зависимости. Снимок нестабилен, потому что он находится в стадии разработки, но если в специальном проекте необходимо внести последние изменения, необходимо настроить версию зависимости на версию снимка. Этот сценарий возникает в больших организациях с несколькими продуктами, которые эти продукты очень тесно связаны друг с другом.

 

Снимок - это специальная версия, которая указывает текущую версию проекта, над которым ведется работа. Для каждой сборки maven всегда проверяет SNAPSHOT проекта.

> 
> Всякий раз, когда maven находит новый SNAPSHOT проекта, он загружает и заменяет старый файл .jar проекта в локальном хранилище.
> 
> 
> 

Снимок версии всегда получает некоторые обновления/изменения, сделанные в проекте. Кроме того, снимок должен существовать только на этапе разработки, и у него не будет продакшен версии. Это означает, что сборка проекта будет изменена в любое время, и он все еще находится в процессе разработки.

Когда вы создаете приложение, Maven будет искать зависимости в локальном хранилище. Если стабильная версия там не найдена, она будет искать в удаленных репозиториях (определенных в pom.xml), чтобы найти эту зависимость. Затем он скопирует его в локальный репозиторий, чтобы сделать его доступным для следующих сборок.