Pull to refresh

Comments 16

А что для создания проксей используется в таких фреймворках, как Spring, Hibernate?
В Hibernate переходят на Byte Buddy
Отличное начало! Теперь каждый из подходов можно развернуть сильней — получится цикл статей о проксировании.
Оно уже достаточно давно висит. И последний пост автора bytebuddy тоже уже давно. Фи гзнает, я движения не особо вижу. На гитхабе надо посмотреть, наверное.
Кто-нибудь может объяснить зачем использовать прокси-классы, если есть наследование?
Можно ведь создать класс — наследник User, переопределить в нем нужные методы, и вместо прокси-класса использовать этот класс-наследник?
Тут фишка в том что к уже созданному экземпляру мы подвязываем дополнительную логику и делаем это в runtime
Dynamic proxy на то и dynamic, что они создаются на лету, в рантайме. На момент компиляции может не быть информации о том, какой класс мы будем проксировать.
Например на лету создать реализацию интерфейса. Класса как такового нету. Есть только прокси создаваемый из/для интерфейчса.

самый простой пример. Аннотации спринга.
Ставите над методом @transactional, а в прокси-классе создается обертка вокруг вызова.
Частый вопрос на собеседовании — сработает ли такая аннотация если вызвать метод из того же класса, где он располагается. ответ — нет, так как произойдет вызов без обертки. чтобы сработал вызов нужно сделать @Autowire класса в себя и вызвать уже через поле.


package ru.incbt.cds.api.rest.function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Okhonchenko Aleksander
 * @since 14.02.2018
 */
@Service
public class App {

    @Autowired
    private App app;

    @Transactional
    public void transactedMethod() {
        //some work with db
    }

    public void someMethod() {
        //вызов без обертки
        transactedMethod();
        //вызов с магической оберткой
        app.transactedMethod();
    }

}
Наверное если мы делаем динамический прокси, было бы логичнее использовать аргументы хэндлера а не завязываться на глобальный объект. Так например CGLib это будет вот так
MethodInterceptor handler = (obj, method ,  args,  proxy) -> {
    if(method.getName().equals("getName")){
        return ((String)proxy.invokeSuper(proxy, args)).toUpperCase() ;
    }
    return proxy.invokeSuper(proxy, args);
};

UFO just landed and posted this here
Sign up to leave a comment.

Articles