• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / mybatis-3 / #3636

25 May 2024 01:05PM CUT coverage: 87.169%. Remained the same
#3636

Pull #3170

github

web-flow
chore(deps): update dependency maven to v3.9.7
Pull Request #3170: chore(deps): update dependency maven to v3.9.7

3537 of 4285 branches covered (82.54%)

9389 of 10771 relevant lines covered (87.17%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/org/apache/ibatis/executor/loader/cglib/CglibProxyFactory.java
1
/*
2
 *    Copyright 2009-2024 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.apache.ibatis.executor.loader.cglib;
17

18
import java.lang.reflect.Method;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22
import java.util.concurrent.locks.ReentrantLock;
23

24
import net.sf.cglib.proxy.Callback;
25
import net.sf.cglib.proxy.Enhancer;
26
import net.sf.cglib.proxy.MethodInterceptor;
27
import net.sf.cglib.proxy.MethodProxy;
28

29
import org.apache.ibatis.executor.loader.AbstractEnhancedDeserializationProxy;
30
import org.apache.ibatis.executor.loader.AbstractSerialStateHolder;
31
import org.apache.ibatis.executor.loader.ProxyFactory;
32
import org.apache.ibatis.executor.loader.ResultLoaderMap;
33
import org.apache.ibatis.executor.loader.WriteReplaceInterface;
34
import org.apache.ibatis.io.Resources;
35
import org.apache.ibatis.logging.Log;
36
import org.apache.ibatis.logging.LogFactory;
37
import org.apache.ibatis.reflection.ExceptionUtil;
38
import org.apache.ibatis.reflection.factory.ObjectFactory;
39
import org.apache.ibatis.reflection.property.PropertyCopier;
40
import org.apache.ibatis.reflection.property.PropertyNamer;
41
import org.apache.ibatis.session.Configuration;
42

43
/**
44
 * @author Clinton Begin
45
 *
46
 * @deprecated Since 3.5.10, use Javassist instead.
47
 */
48
@Deprecated
49
public class CglibProxyFactory implements ProxyFactory {
50

51
  private static final String FINALIZE_METHOD = "finalize";
52
  private static final String WRITE_REPLACE_METHOD = "writeReplace";
53

54
  public CglibProxyFactory() {
×
55
    try {
56
      Resources.classForName("net.sf.cglib.proxy.Enhancer");
×
57
    } catch (Throwable e) {
×
58
      throw new IllegalStateException(
×
59
          "Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath.", e);
60
    }
×
61
  }
×
62

63
  @Override
64
  public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration,
65
      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
66
    return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory,
×
67
        constructorArgTypes, constructorArgs);
68
  }
69

70
  public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
71
      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
72
    return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes,
×
73
        constructorArgs);
74
  }
75

76
  static Object createStaticProxy(Class<?> type, Callback callback, List<Class<?>> constructorArgTypes,
77
      List<Object> constructorArgs) {
78
    LogHolder.log.warn("CglibProxyFactory is deprecated. Use another proxy factory implementation.");
×
79
    Enhancer enhancer = new Enhancer();
×
80
    enhancer.setCallback(callback);
×
81
    enhancer.setSuperclass(type);
×
82
    try {
83
      type.getDeclaredMethod(WRITE_REPLACE_METHOD);
×
84
      // ObjectOutputStream will call writeReplace of objects returned by writeReplace
85
      if (LogHolder.log.isDebugEnabled()) {
×
86
        LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
×
87
      }
88
    } catch (NoSuchMethodException e) {
×
89
      enhancer.setInterfaces(new Class[] { WriteReplaceInterface.class });
×
90
    } catch (SecurityException e) {
×
91
      // nothing to do here
92
    }
×
93
    Object enhanced;
94
    if (constructorArgTypes.isEmpty()) {
×
95
      enhanced = enhancer.create();
×
96
    } else {
97
      Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
×
98
      Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
×
99
      enhanced = enhancer.create(typesArray, valuesArray);
×
100
    }
101
    return enhanced;
×
102
  }
103

104
  private static class EnhancedResultObjectProxyImpl implements MethodInterceptor {
105

106
    private final Class<?> type;
107
    private final ResultLoaderMap lazyLoader;
108
    private final boolean aggressive;
109
    private final Set<String> lazyLoadTriggerMethods;
110
    private final ObjectFactory objectFactory;
111
    private final List<Class<?>> constructorArgTypes;
112
    private final List<Object> constructorArgs;
113
    private final ReentrantLock lock = new ReentrantLock();
×
114

115
    private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration,
116
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
×
117
      this.type = type;
×
118
      this.lazyLoader = lazyLoader;
×
119
      this.aggressive = configuration.isAggressiveLazyLoading();
×
120
      this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
×
121
      this.objectFactory = objectFactory;
×
122
      this.constructorArgTypes = constructorArgTypes;
×
123
      this.constructorArgs = constructorArgs;
×
124
    }
×
125

126
    public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration,
127
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
128
      final Class<?> type = target.getClass();
×
129
      EnhancedResultObjectProxyImpl callback = new EnhancedResultObjectProxyImpl(type, lazyLoader, configuration,
×
130
          objectFactory, constructorArgTypes, constructorArgs);
131
      Object enhanced = createStaticProxy(type, callback, constructorArgTypes, constructorArgs);
×
132
      PropertyCopier.copyBeanProperties(type, target, enhanced);
×
133
      return enhanced;
×
134
    }
135

136
    @Override
137
    public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
138
      final String methodName = method.getName();
×
139
      lock.lock();
×
140
      try {
141
        if (WRITE_REPLACE_METHOD.equals(methodName)) {
×
142
          Object original;
143
          if (constructorArgTypes.isEmpty()) {
×
144
            original = objectFactory.create(type);
×
145
          } else {
146
            original = objectFactory.create(type, constructorArgTypes, constructorArgs);
×
147
          }
148
          PropertyCopier.copyBeanProperties(type, enhanced, original);
×
149
          if (lazyLoader.size() > 0) {
×
150
            return new CglibSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes,
×
151
                constructorArgs);
152
          } else {
153
            return original;
×
154
          }
155
        }
156
        if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
×
157
          if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
×
158
            lazyLoader.loadAll();
×
159
          } else if (PropertyNamer.isSetter(methodName)) {
×
160
            final String property = PropertyNamer.methodToProperty(methodName);
×
161
            lazyLoader.remove(property);
×
162
          } else if (PropertyNamer.isGetter(methodName)) {
×
163
            final String property = PropertyNamer.methodToProperty(methodName);
×
164
            if (lazyLoader.hasLoader(property)) {
×
165
              lazyLoader.load(property);
×
166
            }
167
          }
168
        }
169
        return methodProxy.invokeSuper(enhanced, args);
×
170
      } catch (Throwable t) {
×
171
        throw ExceptionUtil.unwrapThrowable(t);
×
172
      } finally {
173
        lock.unlock();
×
174
      }
175
    }
176
  }
177

178
  private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy
179
      implements MethodInterceptor {
180

181
    private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
182
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
183
      super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
×
184
    }
×
185

186
    public static Object createProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
187
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
188
      final Class<?> type = target.getClass();
×
189
      EnhancedDeserializationProxyImpl callback = new EnhancedDeserializationProxyImpl(type, unloadedProperties,
×
190
          objectFactory, constructorArgTypes, constructorArgs);
191
      Object enhanced = createStaticProxy(type, callback, constructorArgTypes, constructorArgs);
×
192
      PropertyCopier.copyBeanProperties(type, target, enhanced);
×
193
      return enhanced;
×
194
    }
195

196
    @Override
197
    public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
198
      final Object o = super.invoke(enhanced, method, args);
×
199
      return o instanceof AbstractSerialStateHolder ? o : methodProxy.invokeSuper(o, args);
×
200
    }
201

202
    @Override
203
    protected AbstractSerialStateHolder newSerialStateHolder(Object userBean,
204
        Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
205
        List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
206
      return new CglibSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes,
×
207
          constructorArgs);
208
    }
209
  }
210

211
  private static class LogHolder {
212
    private static final Log log = LogFactory.getLog(CglibProxyFactory.class);
×
213
  }
214

215
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc