简体   繁体   English

CGLib的拦截实际上返回了什么?

[英]What does CGLib's intercept actually return?

I'm trying to create my own lazy load implementation using CGLib, but i've faced some strange behavior that I cannot explain. 我正在尝试使用CGLib创建自己的延迟加载实现,但是我遇到了一些我无法解释的奇怪行为。

Here is what i'm doing. 这是我在做什么。
Proxy instance is being created like follows: 正在创建代理实例,如下所示:

public static <T> T newInstance(Long sourceId, SourceMapper<T> sourceMapper) {

    Class<?> proxyTargetType = sourceMapper.getType();
    //mapper will use provided sourceId in order to load real object from the DB
    Function<Long, T> mapper = sourceMapper.getMapper();

    return (T) Enhancer.create(proxyTargetType,
                               new DynamicProxy<>(sourceId, mapper));
}

Here is the usage of the code above: 这是上面代码的用法:

Order order = new Order();
     try {
          //heavy object is being proxied
          long customerTariffId = rs.getLong("customer_tariff_id");
          order.setCustomerTariff(DynamicProxy
                          .newInstance(customerTariffId, CUSTOMER_TARIFF_MAPPER)); 
        }

Heavy object should be loaded only if any of its methods gets invoked: 只有在调用重对象的任何方法时,才应加载它:

public Object intercept(Object obj, Method method, Object[] args,
                        MethodProxy methodProxy) throws Throwable {
    T source = this.getSource(); // loads real object using sourceId and mapper
    if(source == null) return null;
    return method.invoke(source, args);
}

It works perfectly if this.getSource() loads some object. 如果this.getSource()加载某些对象,则它可以完美工作。

But here what i'm getting if we assume, that order.getCustomerTariff() should return null ( this.getSource() will return null ) 但是在这里,如果我们假设我得到的结果是, order.getCustomerTariff()应该返回nullorder.getCustomerTariff() this.getSource()将返回null

LOG.debug("{}", order.getCustomerTariff());          //null    (1)
LOG.debug("{}", order.getCustomerTariff() != null);  //true    (2)

I assume, that for some reason toString() gets invoked at line (2), so i'm getting String null instead of literal null . 我假设,由于某种原因, toString()在第(2)行被调用,所以我得到的是String null而不是文字null That's why it is not equal to a literal null in the comparison clause. 这就是为什么它不等于比较子句中的原义null的原因。
How do you think, is there any way to return a regular null at line (2) and receive a correct value of false during that check? 您如何看待,有没有办法在第(2)行中返回常规null并在该检查期间接收到正确的false值?

EDIT 编辑
Class being proxied looks similar to this: 被代理的类看起来像这样:

public class CustomerTariff extends DomainEntity {

    private Customer customer;
    //some other similar fields
    private Tariff tariff;

    public CustomerTariff() {
    }

    public CustomerTariff(Customer customer
                          Tariff tariff) {
        this.customer = customer;
        this.tariff = tariff;
    }

    public CustomerTariff(Long id, Customer customer,
                          Tariff tariff) {
        super(id);
        this.customer = customer;
        this.tariff = tariff;
    } 
    //getters and setters

    @Override
    public String toString() {
    return "CustomerTariff{" +
            "customer=" + customer +
            ", tariff=" + tariff +
            "} " + super.toString();
    }
}

public abstract class DomainEntity {

    private Long id;

    public DomainEntity() {}

    public DomainEntity(Long id) {
       this.id = id;
    }

    @Override
    public String toString() {
       return "DomainEntity{" +
               "id=" + id +
                '}';
       }
    }

I assume that you are intercepting your toString method from your interceptor and you do not get the interception chain you expect. 我假设您正在从拦截器拦截您的toString方法,并且您没有得到预期的拦截链。 Specify a method filter that only hits the methods you want to intercept and you should get the expected result. 指定仅点击您要拦截的方法的方法过滤器,您应该获得预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM