Elixir Application #
一、Application概述 #
1.1 什么是Application #
Application是Elixir/OTP组织代码和运行时的基本单元,包含:
- 模块和代码
- 配置
- 启动和停止逻辑
1.2 Application结构 #
text
my_app/
├── lib/
│ ├── my_app.ex
│ └── my_app/
│ ├── application.ex
│ └── worker.ex
├── config/
│ ├── config.exs
│ ├── dev.exs
│ ├── prod.exs
│ └── runtime.exs
├── test/
├── mix.exs
└── README.md
二、定义Application #
2.1 Application模块 #
elixir
defmodule MyApp.Application do
use Application
@impl true
def start(_type, _args) do
children = [
MyApp.Worker
]
Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
end
@impl true
def stop(_state) do
:ok
end
end
2.2 mix.exs配置 #
elixir
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :my_app,
version: "0.1.0",
elixir: "~> 1.16",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
def application do
[
extra_applications: [:logger],
mod: {MyApp.Application, []}
]
end
defp deps do
[]
end
end
三、Application生命周期 #
3.1 启动 #
elixir
def start(_type, _args) do
children = [
MyApp.Repo,
MyApp.Cache,
MyApp.Worker
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
3.2 停止 #
elixir
def stop(_state) do
IO.puts("Application stopping")
:ok
end
3.3 启动类型 #
:normal- 正常启动:takeover- 从其他节点接管:failover- 故障转移启动
3.4 prep_stop #
elixir
@impl true
def prep_stop(state) do
IO.puts("Preparing to stop")
state
end
四、Application环境 #
4.1 配置文件 #
elixir
# config/config.exs
import Config
config :my_app,
name: "MyApp",
version: "0.1.0"
config :my_app, MyApp.Repo,
database: "my_app_dev",
username: "postgres",
password: "postgres",
hostname: "localhost"
config :my_app, MyApp.Worker,
batch_size: 100,
timeout: 5000
4.2 环境特定配置 #
elixir
# config/dev.exs
import Config
config :my_app, MyApp.Repo,
show_sensitive_data_on_connection_error: true
# config/prod.exs
import Config
config :my_app, MyApp.Repo,
pool_size: 20
4.3 运行时配置 #
elixir
# config/runtime.exs
import Config
config :my_app, MyApp.Repo,
database: System.get_env("DB_NAME") || "my_app",
username: System.get_env("DB_USER") || "postgres",
password: System.get_env("DB_PASS") || "postgres"
4.4 读取配置 #
elixir
iex(1)> Application.get_env(:my_app, :name)
"MyApp"
iex(2)> Application.get_env(:my_app, MyApp.Worker, [])
[batch_size: 100, timeout: 5000]
iex(3)> Application.fetch_env(:my_app, :name)
{:ok, "MyApp"}
iex(4)> Application.fetch_env!(:my_app, :name)
"MyApp"
4.5 更新配置 #
elixir
iex(1)> Application.put_env(:my_app, :name, "NewName")
:ok
五、Application回调 #
5.1 start_phase #
elixir
def start(_type, _args) do
children = [...]
Supervisor.start_link(children, strategy: :one_for_one)
end
def start_phase(:init, _start_type, _phase_args) do
IO.puts("Init phase")
:ok
end
def start_phase(:migrate, _start_type, _phase_args) do
IO.puts("Migrate phase")
:ok
end
def start_phase(:ready, _start_type, _phase_args) do
IO.puts("Ready phase")
:ok
end
5.2 配置启动阶段 #
elixir
def application do
[
extra_applications: [:logger],
mod: {MyApp.Application, []},
start_phases: [
init: [],
migrate: [],
ready: []
]
]
end
六、依赖Application #
6.1 extra_applications #
elixir
def application do
[
extra_applications: [:logger, :crypto, :ssl]
]
end
6.2 applications(已弃用) #
elixir
def application do
[
applications: [:logger, :crypto]
]
end
6.3 included_applications #
elixir
def application do
[
included_applications: [:my_internal_app]
]
end
七、Application管理 #
7.1 启动Application #
elixir
iex(1)> Application.ensure_all_started(:my_app)
{:ok, []}
iex(2)> Application.start(:my_app)
:ok
7.2 停止Application #
elixir
iex(1)> Application.stop(:my_app)
:ok
7.3 查看Application信息 #
elixir
iex(1)> Application.started_applications()
[{:my_app, 'My Application', '0.1.0'}, ...]
iex(2)> Application.info()
7.4 Application规范 #
elixir
iex(1)> Application.spec(:my_app)
[description: 'My Application', id: [], modules: [...], ...]
八、多Application项目 #
8.1 Umbrella项目 #
text
my_umbrella/
├── apps/
│ ├── app_one/
│ │ ├── lib/
│ │ ├── mix.exs
│ │ └── ...
│ └── app_two/
│ ├── lib/
│ ├── mix.exs
│ └── ...
├── config/
│ └── config.exs
└── mix.exs
8.2 创建Umbrella项目 #
bash
mix new my_umbrella --umbrella
cd my_umbrella/apps
mix new app_one
mix new app_two
8.3 Umbrella mix.exs #
elixir
defmodule MyUmbrella.MixProject do
use Mix.Project
def project do
[
apps_path: "apps",
version: "0.1.0",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
defp deps do
[]
end
end
九、最佳实践 #
9.1 Application模块组织 #
elixir
defmodule MyApp.Application do
use Application
@impl true
def start(_type, _args) do
children = [
MyApp.Repo,
MyApp.Cache,
MyApp.PubSub,
MyApp.Scheduler,
MyAppWeb.Endpoint
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
@impl true
def stop(_state) do
:ok
end
end
9.2 配置组织 #
elixir
# config/config.exs
import Config
config :my_app,
ecto_repos: [MyApp.Repo]
import_config "#{config_env()}.exs"
十、总结 #
本章学习了:
| 特性 | 用途 |
|---|---|
use Application |
定义Application |
start/2 |
启动回调 |
stop/1 |
停止回调 |
Application.get_env |
读取配置 |
config/config.exs |
配置文件 |
准备好学习Release了吗?让我们进入下一章。
最后更新:2026-03-27