предисловие
Только лысина может стать сильнее
Оглядываясь назад на фронт:
- ThreadLocal так просто
- Вы можете войти в дверь за три минуты с многопоточностью!
- Базовые знания многопоточности! После прочтения изучение многопоточности может сделать больше с меньшими затратами
- Механизм блокировки Java для понимания
- AQS просто пройти
- Заблокируйте подкласс, чтобы понять
- Вы действительно хотите знать о пуле потоков?
- Многопоточная взаимоблокировка — это так просто
Многопоточности придет конец.После написания вчера многопоточности я изначально планировал прочитать пункты знаний IO.Позже я посмотрел несколько моделей IO,а потом прочитал "Java Programming Ideas". Я не знаю с чего начать~
видяFilterInputStream
иFilterOutputStream
Я увидел то, что часто слышал раньшеорнамент(Студенты, которые должны знать о IO, могут знать предложение: режим украшения наиболее часто используется в IO)!
Увидев это, вы думаете, я буду говорить о режиме украшения? Нет, сегодня мы поговорим оЧто такое прокси-режим(Он такой тонкий, давай поговорим о режиме украшения завтра~).
Вдохновленный статьей Чжиху @Beautiful Java и «Дзен шаблонов проектирования», я также напишу статью, открывающую мозги.
Как видно из названия, эта статья написана для моей подруги. С тех пор, как она узнала, что я открыла официальный аккаунт, она каждый день читала мои статьи, а когда раньше писала какие-то небольшие алгоритмы, то думала, что программирование — это довольно интересно, и хотела этому научиться.Но, С тех пор, как я начал писать Java-контейнеры и многопоточность, она сказала, что вообще ничего не понимает. Итак, теперь напишемчто-то благородное и легкое для понимания.
GirlFriend girlFriend = new GirlFriend();
sayingProxy(girlFriend);
Тогда давайте начнем.Если в статье есть ошибки, пожалуйста, потерпите меня и поправьте меня в комментариях~
Отказ от ответственности: в этой статье используется JDK1.8.
1. Введение в режим агента
Шаблон прокси — это очень хорошо изученный шаблон проектирования.Агенты повсюду:
- Будучи звездой, Ван Баоцян не может делать все сам (с сериалами, расписанием и т. д.), поэтому он нанял агента.
- Что делать, если хлопотно идти в больницу на регистрацию? Найдите скальпера, который поможет нам зарегистрироваться
- Технического уровня King Glory недостаточно, что мне делать, если я хочу получить более высокий балл? Пожалуйста, тренируйте игру
- Что мне делать, если я напишу незаконный код и попаду в полицию? Попросите юриста помочь нам в судебном процессе
Будь то агент, спекулянт, гейм-бустер или юрист, все онидолжен помочь нам. но ониНе могу сделать все это в одиночкуДа, просто на «я», чтобы разобраться с крохами (вещами, которые мы не хотим делать или не можем делать).
- Режиссер нашел агента Хуан БаоцянаПусть Ван Баоцян снимет фильм!
- бык выстраиватьсядавайте повесим трубку!
- бустер игрымой аккаунт в чате!
- Адвокаты помогают мне с юридическими проблемами, если иск терпеть неудачу,Я все еще сижу в тюрьме!
Другой пример:
- Теперь я интернет-знаменитость с большим количеством подписчиков. Фанаты хотят, чтобы я писал код, чтобы они видели его каждый день, так что я определенно не могу писать код каждый день, я очень занят... Итак, я пошел искать агента. Этот брокер представляет меня. когданесгибаемые фанатыЕсли вы хотите, чтобы я написал код, вы должны сначала найти брокера и сказать ему, что вы хотите, чтобы я написал код.
- Прошло десять лет, а я становился все популярнее,меньше волос. Не то чтобы фанаты хотели, чтобы я писал код, я это делал. Мне будет предъявлено обвинение. Однако как общественный деятель я не могу сказать: я буду писать код только в том случае, если мне нужно будет получить 100 миллионов. Так что это заставляет агента сказать фанатам: всего 100 миллионов, я напишу код.
- Неважно, чего хочет от меня внешний мир, это должно пройти через моего агента. Мой брокер тоже рассматривает сборы, просит их увильнуть.
- Брокер — это агент, и именно я на самом деле пишу код
Итак, режим прокси:То, что текущий объект не хочет и не может делать, делегируется другим объектам., Мне просто нужно хорошо выполнять свой долг!
2. Опишите режим прокси кодом (статический прокси)
Вот интерфейс для программистов, которые пишут код каждый день
public interface Programmer {
// 程序员每天都写代码
void coding();
}
Java3y тоже программист, он же пишет код (код, написанный каждым программистом разный, поэтому он делится на интерфейс и класс реализации)
public class Java3y implements Programmer {
@Override
public void coding() {
System.out.println("Java3y最新文章:......给女朋友讲解什么是代理模式.......");
}
}
В это время Java3y уже стал интернет-знаменитостью, и он не хочет писать скучный код. Он думал: «Хорошо зарабатывать деньги, когда пишешь код. Когда кто-то дает мне деньги, я пишу код».но, письмо Java3y очень плохо, как только появится тофу из зимней дыни, он станет популярной интернет-знаменитостью за считанные минуты, чего Java3y не хочет видеть.
Такие платформы, как Zhihu и Blog Park, такжене можетСтавьте себе лайки для привлечения трафика (-->Текущий объект не может)
Поэтому Java3y наняла **программиста V (агента)** для реализации своего плана.Этот программист V будет лайкать, комментировать и защищать Java3y каждый раз, когда Java3y публикует статью. Пока есть трафик, есть деньги.
public class ProgrammerBigV implements Programmer {
// 指定程序员大V要让谁发文章(先发文章、后点赞)
private Java3y java3y ;
public ProgrammerBigV(Java3y java3y) {
this.java3y = java3y;
}
// 程序员大V点赞评论收藏转发
public void upvote() {
System.out.println("程序员大V点赞评论收藏转发!");
}
@Override
public void coding() {
// 让Java3y发文章
java3y.coding();
// 程序员大V点赞评论收藏转发!
upvote();
}
}
Статья (код) по-прежнему присылается Java3y, но программисту Ви она будет нравиться каждый раз при отправке.
public class Main {
public static void main(String[] args) {
// 想要发达的Java3y
Java3y java3y = new Java3y();
// 受委托程序员大V
Programmer programmer = new ProgrammerBigV(java3y);
// 受委托程序员大V让Java3y发文章,大V(自己)来点赞
programmer.coding();
}
}
Таким образом, прохожие, не знающие правды, думают, что Java3y действительно мощная, а знания платные.
2.1 Прозрачный прокси (обычный прокси)
Спустя какое-то время Java3y почувствовал вкус сладости и понял, что это способ заработать деньги. Итак, Java3y дала программистам достаточно денег, чтобы сделать большой V,Пусть программист Ви занимается только своими делами, не может заниматься чужими делами (сломанный чужой финансовый путь).
Итак, программист большой VТолькоВедение бизнеса Java3y в одиночку:
public class ProgrammerBigV implements Programmer {
// 指定程序员大V要给Java3y点赞
private Java3y java3y ;
// 只做Java3y的生意了
public ProgrammerBigV() {
this.java3y = new Java3y();
}
// 程序员大V点赞评论收藏转发
public void upvote() {
System.out.println("程序员大V点赞评论收藏转发!");
}
@Override
public void coding() {
// 让Java3y发文章了
java3y.coding();
// 程序员大V点赞评论收藏转发!
upvote();
}
}
Поэтому, когда программист V хочет заработать немного денег на карманные расходы, вполне нормально позволить Java3y публиковать статьи.
public class Main {
public static void main(String[] args) {
// 受委托程序员大V
Programmer programmer = new ProgrammerBigV();
// 受委托程序员大V让Java3y发文章,大V来点赞
programmer.coding();
}
}
В настоящее время,Реальные объекты (Java3y) прозрачны для внешнего мира.
2.2 Пользовательский метод прокси-класса
Программист В. увидел, что Java3y идет гладко и приносит много денег. Я подумал, что пришло время повысить цену, поэтому я сказал Java3y после того, как мне понравилосьДобавляйте 100 юаней за каждый лайк!
Итак, программист Ви добавил еще один метод:addMoney()
public class ProgrammerBigV implements Programmer {
// ..省略了上面的代码
// 加价啦
public void addMoney() {
System.out.println("这次我要加100块");
}
@Override
public void coding() {
// 让Java3y发文章了
java3y.coding();
// 程序员大V点赞评论收藏转发!
upvote();
// 加价
addMoney();
}
}
Таким образом, программист V может каждый раз добавлять еще 100:
3. Динамический агент
Прошло несколько лет, а Java3y все еще не заработал состояние, полагаясь на большие симпатии программистов к V (по сути, у Java3y нет галантереи, и она не была признана публикой). В это время многие люди были повышены до программиста V, но предыдущий программист V копил деньги... Хотя вначале Java3y вкусила сладость, но сейчас у Java3y финансы в дефиците.
Java3y считает, что это его провал: это должен быть программист Ви, который открыл мне дверь, чтобы он понравился, и его видели насквозь, и люди, которые едят дыни, знают об этом, и он так много берет.
Так что Java3y не приглашает программистов быть большими V, пожалуйста, как водная армия (водная армия дешева,Какпросто хорошо):
public class Main {
public static void main(String[] args1) {
// Java3y请水军
Java3y java3y = new Java3y();
Programmer programmerWaterArmy = (Programmer) Proxy.newProxyInstance(java3y.getClass().getClassLoader(), java3y.getClass().getInterfaces(), (proxy, method, args) -> {
// 如果是调用coding方法,那么水军就要点赞了
if (method.getName().equals("coding")) {
method.invoke(java3y, args);
System.out.println("我是水军,我来点赞了!");
} else {
// 如果不是调用coding方法,那么调用原对象的方法
return method.invoke(java3y, args);
}
return null;
});
// 每当Java3y写完文章,水军都会点赞
programmerWaterArmy.coding();
}
}
Всякий раз, когда Java3y публикует статью, она нравится Шуй Джуну.
Java3y вздыхает: пожалуйста, военно-морской флот действительноудобныйАх~
3.1 Процесс вызова динамического прокси
Давайте посмотрим, как был приглашен флот:
Java предоставляет класс Proxy, который может генерировать прокси-объект объекта, вызывая его метод newInstance.Для этого метода требуются три параметра:
- Параметр 1: Какой загрузчик классов используется для генерации прокси-объекта [обычно мы используем загрузчик прокси-класса]
- Параметр 2: Сгенерировать прокси объект какого объекта указать через интерфейс [указать интерфейс класса для проксирования]
- Параметр третий: что делать в методе сгенерированного прокси-объекта [реализовать интерфейс обработчика, можем реализовать как хотим]
Прежде чем писать динамические прокси, следует уточнить несколько понятий:
- Прокси-объект имеет те же методы, что и целевой объект [поскольку второй параметр указывает интерфейс объекта, прокси-объект будет реализовывать все методы интерфейса]
- Какой метод пользователь вызывает прокси-объект, вызывает метод вызова процессора. 【Перехвачено】
- Использование динамического прокси-сервера JDK должно иметь интерфейс [для второго параметра требуется интерфейс]
Выше также сказано: прокси-объект будет реализовывать все методы интерфейса, и эти реализованные методы будут переданы нашемуhandlerсправиться с этим!
- Все через динамический проксиВсе методы реализованыпройти через
invoke()
перечислить
такПроцесс вызова динамического проксиЭто выглядит так:
3.2 Разница между статическим прокси и динамическим прокси
Очевидно, что:
- Статический прокси-сервер должен написать свой собственный прокси-класс --> прокси-класс должен реализовать тот же интерфейс, что и целевой объект.
- Динамический прокси не требует написания собственного класса прокси ---> (он генерируется динамически)
При использовании статического прокси:
- Если интерфейс целевого объекта имеетМногие методыЕсли так, то нам все равно придется реализовывать их по одному, что будет более хлопотно
При использовании динамических прокси:
- Генерация прокси-объекта заключается в использовании JDK API,Динамически создавать прокси-объекты в памяти(требует от нас указать тип интерфейса, который реализует прокси-объект/целевой объект) и будетВсе методы, реализующие интерфейс по умолчанию.
4. Типичные области применения
Когда мы раньше писали китайские фильтры, нам нужно было использовать шаблон проектирования упаковки для разработки класса запроса. Если сервлет не предоставляет нам класс реализации, нам будет сложнее использовать шаблон проектирования упаковки.
Теперь, когда мы узнали о динамических прокси, динамические проксиПерехват прямого доступа к объектам — это навык, который можно улучшить для объектов.
4.1 Китайский фильтр
public void doFilter(final ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
//放出去的是代理对象
chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断是不是getParameter方法
if (!method.getName().equals("getParameter")) {
//不是就使用request调用
return method.invoke(request, args);
}
//判断是否是get类型的
if (!request.getMethod().equalsIgnoreCase("get")) {
return method.invoke(request, args);
}
//执行到这里,只能是get类型的getParameter方法了。
String value = (String) method.invoke(request, args);
if (value == null) {
return null;
}
return new String(value.getBytes("ISO8859-1"), "UTF-8");
}
}), response);
}
V. Резюме
Я впервые пишу статью таким образом, примеры могут быть неуместными, надеюсь, вы меня простите~
В этой статье в основном объясняются несколько ключевых моментов режима прокси, на самом деле есть некоторые детали: такие как «обязательный прокси» (прокси-объект можно найти только через прокси-объект, и к прокси-объекту нельзя получить прямой доступ, минуя прокси-объект). Просто он используется реже, так что я не буду говорить об этом~~
Для реализации динамического прокси должен быть интерфейс,Динамический прокси основан на интерфейсе к прокси(реализация всех методов интерфейса), если интерфейса нет, то можно рассматривать cglib proxy.
Агент cglib также называется агентом подкласса.Создает подкласс из памяти для расширения функциональности целевого объекта.!
Я не буду выкладывать здесь код, потому что есть много руководств по прокси для cglib, которые похожи на реализацию динамического прокси~~~
В целом: прокси-режим — это режим, который мы часто используем при написании кода.динамический прокси--> Аспектно-ориентированное программирование. Для получения дополнительной информации, пожалуйста, обратитесь к статье, которую я написал ранее:
На самом деле, помните только одно:Оригинальный объект нуждается в дополнительной функциональности, подумайте о технологии динамических прокси!
Использованная литература:
- Дзен шаблонов проектирования
- Wangjingxin.top/2016/11/16/…
- woo woo woo.cn blog on.com/Drawing Truck Subtropical/…
Если в статье есть какие-либо ошибки, пожалуйста, поправьте меня, и мы сможем общаться друг с другом. Учащиеся, привыкшие читать технические статьи в WeChat и желающие получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y.
Оглавление Навигация по статьям: