Cglib 代理工厂类,为了实现延迟加载属性
1、源码(Cglib代理工厂类)
import java
.lang
.reflect
.Method
;
import java
.util
.List
;
import java
.util
.Map
;
import java
.util
.Properties
;
import java
.util
.Set
;
import net
.sf
.cglib
.proxy
.Callback
;
import net
.sf
.cglib
.proxy
.Enhancer
;
import net
.sf
.cglib
.proxy
.MethodInterceptor
;
import net
.sf
.cglib
.proxy
.MethodProxy
;
import org
.apache
.ibatis
.executor
.loader
.AbstractEnhancedDeserializationProxy
;
import org
.apache
.ibatis
.executor
.loader
.AbstractSerialStateHolder
;
import org
.apache
.ibatis
.executor
.loader
.ProxyFactory
;
import org
.apache
.ibatis
.executor
.loader
.ResultLoaderMap
;
import org
.apache
.ibatis
.executor
.loader
.WriteReplaceInterface
;
import org
.apache
.ibatis
.io
.Resources
;
import org
.apache
.ibatis
.logging
.Log
;
import org
.apache
.ibatis
.logging
.LogFactory
;
import org
.apache
.ibatis
.reflection
.ExceptionUtil
;
import org
.apache
.ibatis
.reflection
.factory
.ObjectFactory
;
import org
.apache
.ibatis
.reflection
.property
.PropertyCopier
;
import org
.apache
.ibatis
.reflection
.property
.PropertyNamer
;
import org
.apache
.ibatis
.session
.Configuration
;
public class CglibProxyFactory implements ProxyFactory {
private static final String FINALIZE_METHOD
= "finalize";
private static final String WRITE_REPLACE_METHOD
= "writeReplace";
public CglibProxyFactory() {
try {
Resources
.classForName("net.sf.cglib.proxy.Enhancer");
} catch (Throwable e
) {
throw new IllegalStateException("Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath.", e
);
}
}
@Override
public Object
createProxy(Object target
, ResultLoaderMap lazyLoader
, Configuration configuration
, ObjectFactory objectFactory
, List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
return EnhancedResultObjectProxyImpl
.createProxy(target
, lazyLoader
, configuration
, objectFactory
, constructorArgTypes
, constructorArgs
);
}
public Object
createDeserializationProxy(Object target
, Map
<String, ResultLoaderMap.LoadPair> unloadedProperties
, ObjectFactory objectFactory
, List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
return EnhancedDeserializationProxyImpl
.createProxy(target
, unloadedProperties
, objectFactory
, constructorArgTypes
, constructorArgs
);
}
@Override
public void setProperties(Properties properties
) {
}
static Object
crateProxy(Class
<?> type
, Callback callback
, List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
Enhancer enhancer
= new Enhancer();
enhancer
.setCallback(callback
);
enhancer
.setSuperclass(type
);
try {
type
.getDeclaredMethod(WRITE_REPLACE_METHOD
);
if (LogHolder
.log
.isDebugEnabled()) {
LogHolder
.log
.debug(WRITE_REPLACE_METHOD
+ " method was found on bean " + type
+ ", make sure it returns this");
}
} catch (NoSuchMethodException e
) {
enhancer
.setInterfaces(new Class[]{WriteReplaceInterface
.class});
} catch (SecurityException e
) {
}
Object enhanced
;
if (constructorArgTypes
.isEmpty()) {
enhanced
= enhancer
.create();
} else {
Class
<?>[] typesArray
= constructorArgTypes
.toArray(new Class[constructorArgTypes
.size()]);
Object
[] valuesArray
= constructorArgs
.toArray(new Object[constructorArgs
.size()]);
enhanced
= enhancer
.create(typesArray
, valuesArray
);
}
return enhanced
;
}
private static class EnhancedResultObjectProxyImpl implements MethodInterceptor {
private final Class
<?> type
;
private final ResultLoaderMap lazyLoader
;
private final boolean aggressive
;
private final Set
<String> lazyLoadTriggerMethods
;
private final ObjectFactory objectFactory
;
private final List
<Class
<?>> constructorArgTypes
;
private final List
<Object> constructorArgs
;
private EnhancedResultObjectProxyImpl(Class
<?> type
, ResultLoaderMap lazyLoader
, Configuration configuration
, ObjectFactory objectFactory
, List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
this.type
= type
;
this.lazyLoader
= lazyLoader
;
this.aggressive
= configuration
.isAggressiveLazyLoading();
this.lazyLoadTriggerMethods
= configuration
.getLazyLoadTriggerMethods();
this.objectFactory
= objectFactory
;
this.constructorArgTypes
= constructorArgTypes
;
this.constructorArgs
= constructorArgs
;
}
public static Object
createProxy(Object target
, ResultLoaderMap lazyLoader
, Configuration configuration
, ObjectFactory objectFactory
, List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
final Class
<?> type
= target
.getClass();
EnhancedResultObjectProxyImpl callback
= new EnhancedResultObjectProxyImpl(type
, lazyLoader
, configuration
, objectFactory
, constructorArgTypes
, constructorArgs
);
Object enhanced
= crateProxy(type
, callback
, constructorArgTypes
, constructorArgs
);
PropertyCopier
.copyBeanProperties(type
, target
, enhanced
);
return enhanced
;
}
@Override
public Object
intercept(Object enhanced
, Method method
, Object
[] args
, MethodProxy methodProxy
) throws Throwable
{
final String methodName
= method
.getName();
try {
synchronized (lazyLoader
) {
if (WRITE_REPLACE_METHOD
.equals(methodName
)) {
Object original
;
if (constructorArgTypes
.isEmpty()) {
original
= objectFactory
.create(type
);
} else {
original
= objectFactory
.create(type
, constructorArgTypes
, constructorArgs
);
}
PropertyCopier
.copyBeanProperties(type
, enhanced
, original
);
if (lazyLoader
.size() > 0) {
return new CglibSerialStateHolder(original
, lazyLoader
.getProperties(), objectFactory
, constructorArgTypes
, constructorArgs
);
} else {
return original
;
}
} else {
if (lazyLoader
.size() > 0 && !FINALIZE_METHOD
.equals(methodName
)) {
if (aggressive
|| lazyLoadTriggerMethods
.contains(methodName
)) {
lazyLoader
.loadAll();
} else if (PropertyNamer
.isSetter(methodName
)) {
final String property
= PropertyNamer
.methodToProperty(methodName
);
lazyLoader
.remove(property
);
} else if (PropertyNamer
.isGetter(methodName
)) {
final String property
= PropertyNamer
.methodToProperty(methodName
);
if (lazyLoader
.hasLoader(property
)) {
lazyLoader
.load(property
);
}
}
}
}
}
return methodProxy
.invokeSuper(enhanced
, args
);
} catch (Throwable t
) {
throw ExceptionUtil
.unwrapThrowable(t
);
}
}
}
private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodInterceptor {
private EnhancedDeserializationProxyImpl(Class
<?> type
, Map
<String, ResultLoaderMap.LoadPair> unloadedProperties
, ObjectFactory objectFactory
,
List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
super(type
, unloadedProperties
, objectFactory
, constructorArgTypes
, constructorArgs
);
}
public static Object
createProxy(Object target
, Map
<String, ResultLoaderMap.LoadPair> unloadedProperties
, ObjectFactory objectFactory
,
List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
final Class
<?> type
= target
.getClass();
EnhancedDeserializationProxyImpl callback
= new EnhancedDeserializationProxyImpl(type
, unloadedProperties
, objectFactory
, constructorArgTypes
, constructorArgs
);
Object enhanced
= crateProxy(type
, callback
, constructorArgTypes
, constructorArgs
);
PropertyCopier
.copyBeanProperties(type
, target
, enhanced
);
return enhanced
;
}
@Override
public Object
intercept(Object enhanced
, Method method
, Object
[] args
, MethodProxy methodProxy
) throws Throwable
{
final Object o
= super.invoke(enhanced
, method
, args
);
return o
instanceof AbstractSerialStateHolder ? o
: methodProxy
.invokeSuper(o
, args
);
}
@Override
protected AbstractSerialStateHolder
newSerialStateHolder(Object userBean
, Map
<String, ResultLoaderMap.LoadPair> unloadedProperties
, ObjectFactory objectFactory
,
List
<Class
<?>> constructorArgTypes
, List
<Object> constructorArgs
) {
return new CglibSerialStateHolder(userBean
, unloadedProperties
, objectFactory
, constructorArgTypes
, constructorArgs
);
}
}
private static class LogHolder {
private static final Log log
= LogFactory
.getLog(CglibProxyFactory
.class);
}
}
1.1、总结
通过cglib创建代理对象,然后实现延迟加载数据,填充某个属性创建代理对象,每次代理调用方法实现,首先会调用MethodInterceptor的intercept方法