← Назад к вопросам
Что в иерархии находится над сессией
2.0 Middle🔥 111 комментариев
#ORM и Hibernate#Базы данных и SQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Иерархия выше Session в веб-приложениях
Краткий ответ
В иерархии веб-приложения Session находится внутри ServletContext, и выше неё расположены следующие уровни:
ApplicationContext (Application scope) — доступно всему приложению
↓
ServletContext — общие ресурсы для всех сессий
↓
HttpSession (Session scope) — данные пользователя в сессии
↓
HttpServletRequest (Request scope) — данные конкретного запроса
1. HttpServletRequest (Request Scope)
Это самый нижний уровень, содержит данные конкретного HTTP запроса:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Request scope — это данные ВНЕ сессии
String username = request.getParameter("username");
String password = request.getParameter("password");
// Проверка аутентификации
if (authenticate(username, password)) {
// Сохраняем пользователя в сессию (Session scope)
HttpSession session = request.getSession(true);
session.setAttribute("user", username);
session.setAttribute("loginTime", new Date());
response.sendRedirect("/dashboard");
}
}
}
Жизненный цикл Request:
1. Клиент отправляет HTTP запрос
2. Сервер создаёт HttpServletRequest
3. Сервлет обрабатывает запрос
4. Сервер отправляет ответ
5. HttpServletRequest удаляется из памяти
2. HttpSession (Session Scope)
Session содержит данные, которые сохраняются между запросами одного пользователя:
public class DashboardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Получаем сессию
HttpSession session = request.getSession(false);
if (session == null) {
// Нет сессии — перенаправляем на login
response.sendRedirect("/login");
return;
}
// Получаем данные из сессии (они сохранены от предыдущего запроса)
String user = (String) session.getAttribute("user");
Date loginTime = (Date) session.getAttribute("loginTime");
// Сессия существует 30 минут (или пока пользователь активен)
}
}
// Фильтр для отслеживания активности сессии
@WebFilter("/*")
public class SessionFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpSession session = httpReq.getSession(false);
if (session != null) {
// Сессия будет истечать через 30 минут неактивности
long lastActivity = (Long) session.getAttribute("lastActivity");
long now = System.currentTimeMillis();
if (now - lastActivity > 30 * 60 * 1000) {
// Сессия устарела
session.invalidate();
} else {
// Обновляем время активности
session.setAttribute("lastActivity", now);
}
}
chain.doFilter(request, response);
}
}
3. ServletContext (Application Scope)
ServletContext содержит данные, которые доступны всему приложению (всем пользователям):
// Инициализация при запуске приложения
@WebListener
public class AppContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
// Данные доступны всему приложению
context.setAttribute("appVersion", "1.0.0");
context.setAttribute("appName", "MyApp");
// Инициализация БД pool'а (доступен всем потокам)
DataSource dataSource = initializeDataSource();
context.setAttribute("dataSource", dataSource);
// Глобальный счётчик пользователей
context.setAttribute("activeUsers", new AtomicInteger(0));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// Очистка ресурсов при выключении приложения
ServletContext context = sce.getServletContext();
DataSource ds = (DataSource) context.getAttribute("dataSource");
if (ds != null) {
// Закрыть соединения
}
}
}
// Использование в сервлете
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = getServletContext();
// Доступ к приложению scope данным
String appVersion = (String) context.getAttribute("appVersion");
DataSource dataSource = (DataSource) context.getAttribute("dataSource");
AtomicInteger activeUsers = (AtomicInteger) context.getAttribute("activeUsers");
// Увеличиваем счётчик активных пользователей
activeUsers.incrementAndGet();
response.getWriter().println("App: " + appVersion);
response.getWriter().println("Active users: " + activeUsers.get());
}
}
ServletContext жизненный цикл:
1. Сервер запускается
2. Сервер создаёт ServletContext для приложения
3. Вызывает ServletContextListener.contextInitialized()
4. Все сервлеты и фильтры могут обращаться к контексту
5. Сервер выключается
6. Вызывает ServletContextListener.contextDestroyed()
7. ServletContext удаляется
4. ApplicationContext (Spring Framework)
В Spring это находится ещё выше — это вся конфигурация приложения:
// Spring Boot Application
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
// ApplicationContext создаётся и инициализируется
}
}
// Spring beans живут в ApplicationContext
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
// Этот bean создаётся один раз для всего приложения
return new HikariDataSource();
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
// Доступ к ApplicationContext из сервлета
@RestController
public class MainController {
private final ApplicationContext context;
@Autowired
public MainController(ApplicationContext context) {
this.context = context;
}
@GetMapping("/beans")
public List<String> getBeans() {
// Доступ ко всем beans в ApplicationContext
return Arrays.asList(context.getBeanDefinitionNames());
}
}
Полная иерархия в Spring WebMvc
┌─────────────────────────────────────┐
│ ApplicationContext (Spring) │ ← Application Scope (синглтоны)
│ - Все beans (Services, DAOs) │
│ - Конфигурация приложения │
│ - Жизненный цикл: Spring up → down │
└──────────────────┬──────────────────┘
│
┌──────────────────▼──────────────────┐
│ ServletContext (всё приложение) │ ← Application Scope (Servlet)
│ - initParameters │
│ - shared attributes │
│ - Доступ: getServletContext() │
└──────────────────┬──────────────────┘
│
┌──────────────────▼──────────────────┐
│ HttpSession (один пользователь) │ ← Session Scope
│ - user ID │
│ - preferences │
│ - Доступ: request.getSession() │
│ - Время жизни: 30 мин без активн. │
└──────────────────┬──────────────────┘
│
┌──────────────────▼──────────────────┐
│ HttpServletRequest (один запрос) │ ← Request Scope
│ - parameters │
│ - headers │
│ - attributes (для форвардинга) │
│ - Доступ: в методе doGet/doPost │
│ - Время жизни: длительность запроса│
└─────────────────────────────────────┘
Практический пример: вся иерархия в действии
@WebListener
public class MyListener implements ServletContextListener, HttpSessionListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// Application Scope
ServletContext ctx = sce.getServletContext();
ctx.setAttribute("appStartTime", new Date());
System.out.println("App started");
}
@Override
public void sessionCreated(HttpSessionEvent se) {
// Session Scope
HttpSession session = se.getSession();
session.setAttribute("sessionStartTime", new Date());
System.out.println("Session created: " + session.getId());
}
}
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Request Scope: get parameters
String name = req.getParameter("name");
// Request Scope: forward to JSP
req.setAttribute("message", "Hello " + name);
// Session Scope
HttpSession session = req.getSession();
Integer visitCount = (Integer) session.getAttribute("visitCount");
if (visitCount == null) visitCount = 0;
visitCount++;
session.setAttribute("visitCount", visitCount);
// Application Scope
ServletContext context = getServletContext();
Date appStartTime = (Date) context.getAttribute("appStartTime");
req.getRequestDispatcher("/example.jsp").forward(req, resp);
}
}
Сравнение scopes
| Scope | Жизненный цикл | Доступ | Примеры |
|---|---|---|---|
| Request | Duration запроса | request.getAttribute() | параметры, заголовки |
| Session | 30 мин без активности | session.getAttribute() | данные пользователя, корзина |
| Application | Запуск-выключение приложения | context.getAttribute() | конфиги, пулы соединений |
| Spring Scope | Зависит от scope bean'а | @Autowired | синглтоны, прототипы, web scopes |
Итоговый вывод
В иерархии выше Session находятся:
- HttpServletRequest (Request scope) — самый узкий, один запрос
- HttpSession — один пользователь, несколько запросов
- ServletContext — всё приложение, все пользователи
- ApplicationContext (Spring) — вся инфраструктура приложения
Всё это скоординировано в слоистой архитектуре Servlet API, где каждый уровень имеет свой жизненный цикл и область видимости.