下面列出了java.lang.reflect.Proxy#isProxyClass ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
final ClassLoader cl = getClassLoader0();
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
// skip the package access check on a proxy class in default proxy package
String pkg = name.substring(0, i);
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
final ClassLoader cl = getClassLoader0();
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
// skip the package access check on a proxy class in default proxy package
String pkg = name.substring(0, i);
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
}
@Override
public ObjectInputFilter.Status checkInput(FilterInfo filter) {
Class<?> serialClass = filter.serialClass();
System.out.printf(" checkInput: class: %s, arrayLen: %d, refs: %d, depth: %d, bytes; %d%n",
serialClass, filter.arrayLength(), filter.references(),
filter.depth(), filter.streamBytes());
count++;
if (serialClass != null) {
if (serialClass.getName().contains("$$Lambda$")) {
// TBD: proper identification of serialized Lambdas?
// Fold the serialized Lambda into the SerializedLambda type
classes.add(SerializedLambda.class);
} else if (Proxy.isProxyClass(serialClass)) {
classes.add(Proxy.class);
} else {
classes.add(serialClass);
}
}
this.maxArray = Math.max(this.maxArray, filter.arrayLength());
this.maxRefs = Math.max(this.maxRefs, filter.references());
this.maxDepth = Math.max(this.maxDepth, filter.depth());
this.maxBytes = Math.max(this.maxBytes, filter.streamBytes());
return ObjectInputFilter.Status.UNDECIDED;
}
@Override
public Object invoke(Model delegate, Method method, Object[] args) throws Exception {
if(args.length != 1 || args[0] == null) {
return false;
}
Object other = args[0];
if(Proxy.isProxyClass(other.getClass())) {
InvocationHandler handler = Proxy.getInvocationHandler(other);
if(handler instanceof ModelInvocationHandler) {
return delegate.equals(((ModelInvocationHandler) handler).getDelegate());
}
}
if(other instanceof Model) {
return delegate.equals(other);
}
return false;
}
@Override
public Object onHandlerLocationListener(Object listener) {
if (!Proxy.isProxyClass(listener.getClass())) {
// 创建代理类
return Proxy.newProxyInstance(
listener.getClass().getClassLoader(),
listener.getClass().getInterfaces(),
new AMapLocationListenerProxy(listener));
}
return listener;
}
/**
* Handles java.lang.Object methods.
**/
private Object invokeObjectMethod(Object proxy,
Method method,
Object[] args)
{
String name = method.getName();
if (name.equals("hashCode")) {
return hashCode();
} else if (name.equals("equals")) {
Object obj = args[0];
InvocationHandler hdlr;
return
proxy == obj ||
(obj != null &&
Proxy.isProxyClass(obj.getClass()) &&
(hdlr = Proxy.getInvocationHandler(obj)) instanceof RemoteObjectInvocationHandler &&
this.equals(hdlr));
} else if (name.equals("toString")) {
return proxyToString(proxy);
} else {
throw new IllegalArgumentException(
"unexpected Object method: " + method);
}
}
static boolean equal(Object o1, Object o2, NamedMXBeans namedMXBeans) {
if (o1 == o2)
return true;
if (o1 == null || o2 == null)
return false;
if (o1.getClass().isArray()) {
if (!o2.getClass().isArray())
return false;
return deepEqual(o1, o2, namedMXBeans);
}
if (o1 instanceof Map) {
if (!(o2 instanceof Map))
return false;
return equalMap((Map) o1, (Map) o2, namedMXBeans);
}
if (o1 instanceof CompositeData && o2 instanceof CompositeData) {
return compositeDataEqual((CompositeData) o1, (CompositeData) o2,
namedMXBeans);
}
if (Proxy.isProxyClass(o1.getClass())) {
if (Proxy.isProxyClass(o2.getClass()))
return proxyEqual(o1, o2, namedMXBeans);
InvocationHandler ih = Proxy.getInvocationHandler(o1);
// if (ih instanceof MXBeanInvocationHandler) {
// return proxyEqualsObject((MXBeanInvocationHandler) ih,
// o2, namedMXBeans);
if (ih instanceof MBeanServerInvocationHandler) {
return true;
} else if (ih instanceof CompositeDataInvocationHandler) {
return o2.equals(o1);
// We assume the other object has a reasonable equals method
}
} else if (Proxy.isProxyClass(o2.getClass()))
return equal(o2, o1, namedMXBeans);
return o1.equals(o2);
}
public CacheOperationMetadata(CacheOperation operation, Method method, Class<?> targetClass,
KeyGenerator keyGenerator, CacheResolver cacheResolver) {
this.operation = operation;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.targetClass = targetClass;
this.targetMethod = (!Proxy.isProxyClass(targetClass) ?
AopUtils.getMostSpecificMethod(method, targetClass) : this.method);
this.methodKey = new AnnotatedElementKey(this.targetMethod, targetClass);
this.keyGenerator = keyGenerator;
this.cacheResolver = cacheResolver;
}
/**
* Select methods on the given target type based on the lookup of associated metadata.
* <p>Callers define methods of interest through the {@link MetadataLookup} parameter,
* allowing to collect the associated metadata into the result map.
* @param targetType the target type to search methods on
* @param metadataLookup a {@link MetadataLookup} callback to inspect methods of interest,
* returning non-null metadata to be associated with a given method if there is a match,
* or {@code null} for no match
* @return the selected methods associated with their metadata (in the order of retrieval),
* or an empty map in case of no match
*/
public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) {
final Map<Method, T> methodMap = new LinkedHashMap<>();
Set<Class<?>> handlerTypes = new LinkedHashSet<>();
Class<?> specificHandlerType = null;
if (!Proxy.isProxyClass(targetType)) {
specificHandlerType = ClassUtils.getUserClass(targetType);
handlerTypes.add(specificHandlerType);
}
handlerTypes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetType));
for (Class<?> currentHandlerType : handlerTypes) {
final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
ReflectionUtils.doWithMethods(currentHandlerType, method -> {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
T result = metadataLookup.inspect(specificMethod);
if (result != null) {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {
methodMap.put(specificMethod, result);
}
}
}, ReflectionUtils.USER_DECLARED_METHODS);
}
return methodMap;
}
@SuppressWarnings("unchecked")
public static <T, V extends T> Class<T> getMockedType(final V proxy) {
if (Proxy.isProxyClass(proxy.getClass())) {
return (Class<T>) proxy.getClass().getInterfaces()[0];
}
return (Class<T>) proxy.getClass().getSuperclass();
}
private static Object annotationToField(Object x) {
// An annotation element cannot have a null value but never mind
if (x == null)
return null;
if (x instanceof Number || x instanceof String ||
x instanceof Character || x instanceof Boolean ||
x instanceof String[])
return x;
// Remaining possibilities: array of primitive (e.g. int[]),
// enum, class, array of enum or class.
Class<?> c = x.getClass();
if (c.isArray()) {
if (c.getComponentType().isPrimitive())
return x;
Object[] xx = (Object[]) x;
String[] ss = new String[xx.length];
for (int i = 0; i < xx.length; i++)
ss[i] = (String) annotationToField(xx[i]);
return ss;
}
if (x instanceof Class<?>)
return ((Class<?>) x).getName();
if (x instanceof Enum<?>)
return ((Enum<?>) x).name();
// The only other possibility is that the value is another
// annotation, or that the language has evolved since this code
// was written. We don't allow for either of those currently.
// If it is indeed another annotation, then x will be a proxy
// with an unhelpful name like $Proxy2. So we extract the
// proxy's interface to use that in the exception message.
if (Proxy.isProxyClass(c))
c = c.getInterfaces()[0]; // array "can't be empty"
throw new IllegalArgumentException("Illegal type for annotation " +
"element using @DescriptorKey: " + c.getName());
}
/**
* <code>writeObject</code> for custom serialization.
*
* <p>This method writes this object's serialized form for
* this class as follows:
*
* <p>The <code>writeObject</code> method is invoked on
* <code>out</code> passing this object's unique identifier
* (a {@link java.rmi.server.UID UID} instance) as the argument.
*
* <p>Next, the {@link
* java.rmi.server.RemoteRef#getRefClass(java.io.ObjectOutput)
* getRefClass} method is invoked on the activator's
* <code>RemoteRef</code> instance to obtain its external ref
* type name. Next, the <code>writeUTF</code> method is
* invoked on <code>out</code> with the value returned by
* <code>getRefClass</code>, and then the
* <code>writeExternal</code> method is invoked on the
* <code>RemoteRef</code> instance passing <code>out</code>
* as the argument.
*
* @serialData The serialized data for this class comprises a
* <code>java.rmi.server.UID</code> (written with
* <code>ObjectOutput.writeObject</code>) followed by the
* external ref type name of the activator's
* <code>RemoteRef</code> instance (a string written with
* <code>ObjectOutput.writeUTF</code>), followed by the
* external form of the <code>RemoteRef</code> instance as
* written by its <code>writeExternal</code> method.
*
* <p>The external ref type name of the
* <code>RemoteRef</Code> instance is
* determined using the definitions of external ref type
* names specified in the {@link java.rmi.server.RemoteObject
* RemoteObject} <code>writeObject</code> method
* <b>serialData</b> specification. Similarly, the data
* written by the <code>writeExternal</code> method and read
* by the <code>readExternal</code> method of
* <code>RemoteRef</code> implementation classes
* corresponding to each of the defined external ref type
* names is specified in the {@link
* java.rmi.server.RemoteObject RemoteObject}
* <code>writeObject</code> method <b>serialData</b>
* specification.
**/
private void writeObject(ObjectOutputStream out)
throws IOException, ClassNotFoundException
{
out.writeObject(uid);
RemoteRef ref;
if (activator instanceof RemoteObject) {
ref = ((RemoteObject) activator).getRef();
} else if (Proxy.isProxyClass(activator.getClass())) {
InvocationHandler handler = Proxy.getInvocationHandler(activator);
if (!(handler instanceof RemoteObjectInvocationHandler)) {
throw new InvalidObjectException(
"unexpected invocation handler");
}
ref = ((RemoteObjectInvocationHandler) handler).getRef();
} else {
throw new InvalidObjectException("unexpected activator type");
}
out.writeUTF(ref.getRefClass(out));
ref.writeExternal(out);
}
/**
* Processes a method invocation made on the encapsulating
* proxy instance, <code>proxy</code>, and returns the result.
*
* <p><code>RemoteObjectInvocationHandler</code> implements this method
* as follows:
*
* <p>If <code>method</code> is one of the following methods, it
* is processed as described below:
*
* <ul>
*
* <li>{@link Object#hashCode Object.hashCode}: Returns the hash
* code value for the proxy.
*
* <li>{@link Object#equals Object.equals}: Returns <code>true</code>
* if the argument (<code>args[0]</code>) is an instance of a dynamic
* proxy class and this invocation handler is equal to the invocation
* handler of that argument, and returns <code>false</code> otherwise.
*
* <li>{@link Object#toString Object.toString}: Returns a string
* representation of the proxy.
* </ul>
*
* <p>Otherwise, a remote call is made as follows:
*
* <ul>
* <li>If <code>proxy</code> is not an instance of the interface
* {@link Remote}, then an {@link IllegalArgumentException} is thrown.
*
* <li>Otherwise, the {@link RemoteRef#invoke invoke} method is invoked
* on this invocation handler's <code>RemoteRef</code>, passing
* <code>proxy</code>, <code>method</code>, <code>args</code>, and the
* method hash (defined in section 8.3 of the "Java Remote Method
* Invocation (RMI) Specification") for <code>method</code>, and the
* result is returned.
*
* <li>If an exception is thrown by <code>RemoteRef.invoke</code> and
* that exception is a checked exception that is not assignable to any
* exception in the <code>throws</code> clause of the method
* implemented by the <code>proxy</code>'s class, then that exception
* is wrapped in an {@link UnexpectedException} and the wrapped
* exception is thrown. Otherwise, the exception thrown by
* <code>invoke</code> is thrown by this method.
* </ul>
*
* <p>The semantics of this method are unspecified if the
* arguments could not have been produced by an instance of some
* valid dynamic proxy class containing this invocation handler.
*
* @param proxy the proxy instance that the method was invoked on
* @param method the <code>Method</code> instance corresponding to the
* interface method invoked on the proxy instance
* @param args an array of objects containing the values of the
* arguments passed in the method invocation on the proxy instance, or
* <code>null</code> if the method takes no arguments
* @return the value to return from the method invocation on the proxy
* instance
* @throws Throwable the exception to throw from the method invocation
* on the proxy instance
**/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
if (! Proxy.isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("not a proxy");
}
if (Proxy.getInvocationHandler(proxy) != this) {
throw new IllegalArgumentException("handler mismatch");
}
if (method.getDeclaringClass() == Object.class) {
return invokeObjectMethod(proxy, method, args);
} else if ("finalize".equals(method.getName()) && method.getParameterCount() == 0 &&
!allowFinalizeInvocation) {
return null; // ignore
} else {
return invokeRemoteMethod(proxy, method, args);
}
}
/**
* Determine the complete set of interfaces to proxy for the given AOP configuration.
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
* {@link org.springframework.aop.SpringProxy} marker interface.
* @param advised the proxy config
* @param decoratingProxy whether to expose the {@link DecoratingProxy} interface
* @return the complete set of interfaces to proxy
* @since 4.3
* @see SpringProxy
* @see Advised
* @see DecoratingProxy
*/
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}
public static void main(String[] args) throws Exception {
RemoteInterface server = null;
RemoteInterface proxy = null;
try {
System.setProperty("java.rmi.server.ignoreStubClasses", args[0]);
boolean ignoreStubClasses = Boolean.parseBoolean(args[0]);
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
System.err.println("export object");
server = new UseDynamicProxies();
proxy =
(RemoteInterface) UnicastRemoteObject.exportObject(server, 0);
System.err.println("proxy = " + proxy);
if (ignoreStubClasses) {
if (!Proxy.isProxyClass(proxy.getClass())) {
throw new RuntimeException(
"server proxy is not a dynamic proxy");
}
if (!(Proxy.getInvocationHandler(proxy) instanceof
RemoteObjectInvocationHandler))
{
throw new RuntimeException("invalid invocation handler");
}
} else if (!(proxy instanceof RemoteStub)) {
throw new RuntimeException(
"server proxy is not a RemoteStub");
}
System.err.println("invoke methods");
Object obj = proxy.passObject(proxy);
if (!proxy.equals(obj)) {
throw new RuntimeException("returned proxy not equal");
}
int x = proxy.passInt(53);
if (x != 53) {
throw new RuntimeException("returned int not equal");
}
String string = proxy.passString("test");
if (!string.equals("test")) {
throw new RuntimeException("returned string not equal");
}
System.err.println("TEST PASSED");
} finally {
if (proxy != null) {
UnicastRemoteObject.unexportObject(server, true);
}
}
}
/**
* <code>writeObject</code> for custom serialization.
*
* <p>This method writes this object's serialized form for
* this class as follows:
*
* <p>The <code>writeObject</code> method is invoked on
* <code>out</code> passing this object's unique identifier
* (a {@link java.rmi.server.UID UID} instance) as the argument.
*
* <p>Next, the {@link
* java.rmi.server.RemoteRef#getRefClass(java.io.ObjectOutput)
* getRefClass} method is invoked on the activator's
* <code>RemoteRef</code> instance to obtain its external ref
* type name. Next, the <code>writeUTF</code> method is
* invoked on <code>out</code> with the value returned by
* <code>getRefClass</code>, and then the
* <code>writeExternal</code> method is invoked on the
* <code>RemoteRef</code> instance passing <code>out</code>
* as the argument.
*
* @serialData The serialized data for this class comprises a
* <code>java.rmi.server.UID</code> (written with
* <code>ObjectOutput.writeObject</code>) followed by the
* external ref type name of the activator's
* <code>RemoteRef</code> instance (a string written with
* <code>ObjectOutput.writeUTF</code>), followed by the
* external form of the <code>RemoteRef</code> instance as
* written by its <code>writeExternal</code> method.
*
* <p>The external ref type name of the
* <code>RemoteRef</Code> instance is
* determined using the definitions of external ref type
* names specified in the {@link java.rmi.server.RemoteObject
* RemoteObject} <code>writeObject</code> method
* <b>serialData</b> specification. Similarly, the data
* written by the <code>writeExternal</code> method and read
* by the <code>readExternal</code> method of
* <code>RemoteRef</code> implementation classes
* corresponding to each of the defined external ref type
* names is specified in the {@link
* java.rmi.server.RemoteObject RemoteObject}
* <code>writeObject</code> method <b>serialData</b>
* specification.
**/
private void writeObject(ObjectOutputStream out)
throws IOException, ClassNotFoundException
{
out.writeObject(uid);
RemoteRef ref;
if (activator instanceof RemoteObject) {
ref = ((RemoteObject) activator).getRef();
} else if (Proxy.isProxyClass(activator.getClass())) {
InvocationHandler handler = Proxy.getInvocationHandler(activator);
if (!(handler instanceof RemoteObjectInvocationHandler)) {
throw new InvalidObjectException(
"unexpected invocation handler");
}
ref = ((RemoteObjectInvocationHandler) handler).getRef();
} else {
throw new InvalidObjectException("unexpected activator type");
}
out.writeUTF(ref.getRefClass(out));
ref.writeExternal(out);
}
/**
* Reads in and returns class descriptor for a dynamic proxy class. Sets
* passHandle to proxy class descriptor's assigned handle. If proxy class
* descriptor cannot be resolved to a class in the local VM, a
* ClassNotFoundException is associated with the descriptor's handle.
*/
private ObjectStreamClass readProxyDesc(boolean unshared)
throws IOException
{
if (bin.readByte() != TC_PROXYCLASSDESC) {
throw new InternalError();
}
ObjectStreamClass desc = new ObjectStreamClass();
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
passHandle = NULL_HANDLE;
int numIfaces = bin.readInt();
if (numIfaces > 65535) {
throw new InvalidObjectException("interface limit exceeded: "
+ numIfaces);
}
String[] ifaces = new String[numIfaces];
for (int i = 0; i < numIfaces; i++) {
ifaces[i] = bin.readUTF();
}
Class<?> cl = null;
ClassNotFoundException resolveEx = null;
bin.setBlockDataMode(true);
try {
if ((cl = resolveProxyClass(ifaces)) == null) {
resolveEx = new ClassNotFoundException("null class");
} else if (!Proxy.isProxyClass(cl)) {
throw new InvalidClassException("Not a proxy");
} else {
// ReflectUtil.checkProxyPackageAccess makes a test
// equivalent to isCustomSubclass so there's no need
// to condition this call to isCustomSubclass == true here.
ReflectUtil.checkProxyPackageAccess(
getClass().getClassLoader(),
cl.getInterfaces());
// Filter the interfaces
for (Class<?> clazz : cl.getInterfaces()) {
filterCheck(clazz, -1);
}
}
} catch (ClassNotFoundException ex) {
resolveEx = ex;
}
// Call filterCheck on the class before reading anything else
filterCheck(cl, -1);
skipCustomData();
try {
totalObjectRefs++;
depth++;
desc.initProxy(cl, resolveEx, readClassDesc(false));
} finally {
depth--;
}
handles.finish(descHandle);
passHandle = descHandle;
return desc;
}
/**
* Determine the complete set of interfaces to proxy for the given AOP configuration.
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
* {@link org.springframework.aop.SpringProxy} marker interface.
* @param advised the proxy config
* @param decoratingProxy whether to expose the {@link DecoratingProxy} interface
* @return the complete set of interfaces to proxy
* @since 4.3
* @see SpringProxy
* @see Advised
* @see DecoratingProxy
*/
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}
/**
* Check whether the given object is a JDK dynamic proxy.
* <p>This method goes beyond the implementation of
* {@link Proxy#isProxyClass(Class)} by additionally checking if the
* given object is an instance of {@link SpringProxy}.
* @param object the object to check
* @see java.lang.reflect.Proxy#isProxyClass
*/
public static boolean isJdkDynamicProxy(@Nullable Object object) {
return (object instanceof SpringProxy && Proxy.isProxyClass(object.getClass()));
}