[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-patterny-chto-takoe-pattern-proxy":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":16,"progress":17,"seo":18},1265,"chto-takoe-pattern-proxy",40,"patterny","Паттерны","🧩","Что такое паттерн Proxy?","Proxy -- паттерн, предоставляющий объект-заместитель, который контролирует доступ к другому объекту.\n\n> Аналогия из жизни: Proxy -- как секретарь руководителя. Все звонки идут через секретаря, который решает: передать ли звонок, записать сообщение, отказать или добавить информацию к запросу.\n\n\u003Cdetails>\n\u003Csummary>Статический Proxy -- пример\u003C\u002Fsummary>\n\n```java\ninterface UserService {\n    User findById(Long id);\n}\n\nclass UserServiceImpl implements UserService {\n    public User findById(Long id) {\n        return database.query(\"SELECT * FROM users WHERE id = ?\", id);\n    }\n}\n\n\u002F\u002F Proxy: кэширование\nclass CachingUserServiceProxy implements UserService {\n    private final UserService delegate;\n    private final Map\u003CLong, User> cache = new ConcurrentHashMap\u003C>();\n\n    CachingUserServiceProxy(UserService delegate) { this.delegate = delegate; }\n\n    public User findById(Long id) {\n        return cache.computeIfAbsent(id, delegate::findById);\n    }\n}\n\n\u002F\u002F Proxy: логирование\nclass LoggingUserServiceProxy implements UserService {\n    private final UserService delegate;\n\n    public User findById(Long id) {\n        log.info(\"findById called with id={}\", id);\n        User result = delegate.findById(id);\n        log.info(\"findById returned: {}\", result);\n        return result;\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>JDK Dynamic Proxy\u003C\u002Fsummary>\n\n```java\nUserService proxy = (UserService) Proxy.newProxyInstance(\n    UserService.class.getClassLoader(),\n    new Class[]{UserService.class},\n    (proxyObj, method, args) -> {\n        log.info(\"Вызов: {}\", method.getName());\n        long start = System.nanoTime();\n        Object result = method.invoke(realService, args);\n        log.info(\"Время: {} мс\", (System.nanoTime() - start) \u002F 1_000_000);\n        return result;\n    }\n);\n```\n\n\u003C\u002Fdetails>\n\n### Виды Proxy\n\n| Вид | Назначение | Пример |\n|-----|-----------|--------|\n| Virtual Proxy | Ленивая загрузка | Hibernate Lazy Loading |\n| Protection Proxy | Контроль доступа | Spring Security `@PreAuthorize` |\n| Caching Proxy | Кэширование | Spring `@Cacheable` |\n| Logging Proxy | Логирование | Spring AOP |\n\n### Важное\n\n- Spring AOP построен на Proxy: `@Transactional`, `@Cacheable`, `@Async` работают через прокси\n- JDK Dynamic Proxy -- для интерфейсов; CGLIB -- для классов (наследование)\n\n### Частые ошибки\n\n- Вызов метода внутри того же класса -- Spring Proxy не перехватывает self-invocation: `this.method()` обходит прокси\n- Proxy на final-класс -- CGLIB не может создать прокси для final-класса\n\n### Как используется в 2026\n\n- Spring AOP: `@Transactional`, `@Cacheable`, `@Async`, `@PreAuthorize` -- всё через Proxy\n- Hibernate Lazy Loading -- Proxy для отложенной загрузки сущностей\n\n> **На собеседовании:** ключевой вопрос -- self-invocation в Spring. Объясните, почему `this.method()` обходит прокси и как это решить (через `AopContext` или вынос в другой бин). Частая ошибка -- не знать разницу между JDK Dynamic Proxy и CGLIB.","","junior",[15],"patterns",[],null,{"title":19,"description":20,"ogTitle":19,"ogDescription":21,"keywords":22,"schemaAnswer":20,"featuredSnippetReady":23},"Что такое паттерн Singleton? — Gymterview","Singleton -- паттерн, гарантирующий, что у класса есть только один экземпляр, и предоставляющий глобальную точку доступа к нему.","Singleton -- паттерн, гарантирующий, что у класса есть только один экземпляр, и предоставляющий глобальную точку доступа",[15,13],true]