下面列出了java.lang.reflect.Proxy#getProxyClass ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Return a proxy class that implements the interfaces named in a proxy
* class descriptor. Do this using the class loader assigned to this
* Context.
*/
@Override
protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException {
Class<?>[] cinterfaces = new Class[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
cinterfaces[i] = classLoader.loadClass(interfaces[i]);
}
try {
return Proxy.getProxyClass(classLoader, cinterfaces);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
/**
* Generate proxy class descriptors.
*/
ObjectStreamClass[] genDescs() {
ClassLoader ldr = ProxyClassDesc.class.getClassLoader();
Class[] ifaces = new Class[3];
Class[] a =
new Class[] { A1.class, A2.class, A3.class, A4.class, A5.class };
Class[] b =
new Class[] { B1.class, B2.class, B3.class, B4.class, B5.class };
Class[] c =
new Class[] { C1.class, C2.class, C3.class, C4.class, C5.class };
ObjectStreamClass[] descs =
new ObjectStreamClass[a.length * b.length * c.length];
int n = 0;
for (int i = 0; i < a.length; i++) {
ifaces[0] = a[i];
for (int j = 0; j < b.length; j++) {
ifaces[1] = b[j];
for (int k = 0; k < c.length; k++) {
ifaces[2] = c[k];
Class proxyClass = Proxy.getProxyClass(ldr, ifaces);
descs[n++] = ObjectStreamClass.lookup(proxyClass);
}
}
}
return descs;
}
/**
* Generate proxy arrays.
*/
Proxy[][] genArrays(int size, int narrays) throws Exception {
Class proxyClass =
Proxy.getProxyClass(DummyInterface.class.getClassLoader(),
new Class[] { DummyInterface.class });
Constructor proxyCons =
proxyClass.getConstructor(new Class[] { InvocationHandler.class });
Object[] consArgs = new Object[] { new DummyHandler() };
Proxy[][] arrays = new Proxy[narrays][size];
for (int i = 0; i < narrays; i++) {
for (int j = 0; j < size; j++) {
arrays[i][j] = (Proxy) proxyCons.newInstance(consArgs);
}
}
return arrays;
}
public void run() throws Exception {
boolean hasAccess = loader != null || hasAccess();
try {
proxyClass = Proxy.getProxyClass(loader, interfaces);
if (!hasAccess) {
throw new RuntimeException("should have no permission to create proxy class");
}
} catch (AccessControlException e) {
if (hasAccess) {
throw e;
}
if (e.getPermission().getClass() != RuntimePermission.class ||
!e.getPermission().getName().equals("getClassLoader")) {
throw e;
}
return;
}
if (Modifier.isPublic(proxyClass.getModifiers())) {
throw new RuntimeException(proxyClass + " must be non-public");
}
newProxyInstance();
newInstanceFromConstructor(proxyClass);
}
public void run() throws Exception {
boolean hasAccess = loader != null || hasAccess();
try {
proxyClass = Proxy.getProxyClass(loader, interfaces);
if (!hasAccess) {
throw new RuntimeException("should have no permission to create proxy class");
}
} catch (AccessControlException e) {
if (hasAccess) {
throw e;
}
if (e.getPermission().getClass() != RuntimePermission.class ||
!e.getPermission().getName().equals("getClassLoader")) {
throw e;
}
return;
}
if (Modifier.isPublic(proxyClass.getModifiers())) {
throw new RuntimeException(proxyClass + " must be non-public");
}
newProxyInstance();
newInstanceFromConstructor(proxyClass);
}
/**
* Generate proxy arrays.
*/
Proxy[][] genArrays(int size, int narrays) throws Exception {
Class proxyClass =
Proxy.getProxyClass(DummyInterface.class.getClassLoader(),
new Class[] { DummyInterface.class });
Constructor proxyCons =
proxyClass.getConstructor(new Class[] { InvocationHandler.class });
Object[] consArgs = new Object[] { new DummyHandler() };
Proxy[][] arrays = new Proxy[narrays][size];
for (int i = 0; i < narrays; i++) {
for (int j = 0; j < size; j++) {
arrays[i][j] = (Proxy) proxyCons.newInstance(consArgs);
}
}
return arrays;
}
/**
* Generate proxy class descriptors.
*/
ObjectStreamClass[] genDescs() {
ClassLoader ldr = ProxyClassDesc.class.getClassLoader();
Class[] ifaces = new Class[3];
Class[] a =
new Class[] { A1.class, A2.class, A3.class, A4.class, A5.class };
Class[] b =
new Class[] { B1.class, B2.class, B3.class, B4.class, B5.class };
Class[] c =
new Class[] { C1.class, C2.class, C3.class, C4.class, C5.class };
ObjectStreamClass[] descs =
new ObjectStreamClass[a.length * b.length * c.length];
int n = 0;
for (int i = 0; i < a.length; i++) {
ifaces[0] = a[i];
for (int j = 0; j < b.length; j++) {
ifaces[1] = b[j];
for (int k = 0; k < c.length; k++) {
ifaces[2] = c[k];
Class proxyClass = Proxy.getProxyClass(ldr, ifaces);
descs[n++] = ObjectStreamClass.lookup(proxyClass);
}
}
}
return descs;
}
public void run() throws Exception {
boolean hasAccess = loader != null || hasAccess();
try {
proxyClass = Proxy.getProxyClass(loader, interfaces);
if (!hasAccess) {
throw new RuntimeException("should have no permission to create proxy class");
}
} catch (AccessControlException e) {
if (hasAccess) {
throw e;
}
if (e.getPermission().getClass() != RuntimePermission.class ||
!e.getPermission().getName().equals("getClassLoader")) {
throw e;
}
return;
}
if (Modifier.isPublic(proxyClass.getModifiers())) {
throw new RuntimeException(proxyClass + " must be non-public");
}
newProxyInstance();
newInstanceFromConstructor(proxyClass);
}
/**
* ObjectInputStream.resolveProxyClass has some funky way of using
* the incorrect class loader to resolve proxy classes, let's do it our way instead
*/
@Override
protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException {
ClassLoader latestLoader;
if (classLoaders != null && classLoaders.length > 0) {
latestLoader = classLoaders[0];
} else {
latestLoader = null;
}
ClassLoader nonPublicLoader = null;
boolean hasNonPublicInterface = false;
// define proxy in class loader of non-public interface(s), if any
Class<?>[] classObjs = new Class[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
Class<?> cl = this.resolveClass(interfaces[i]);
if (latestLoader==null) latestLoader = cl.getClassLoader();
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
if (hasNonPublicInterface) {
if (nonPublicLoader != cl.getClassLoader()) {
throw new IllegalAccessError(
sm.getString("replicationStream.conflict"));
}
} else {
nonPublicLoader = cl.getClassLoader();
hasNonPublicInterface = true;
}
}
classObjs[i] = cl;
}
try {
return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader
: latestLoader, classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
protected Class<?> resolveProxyClass(String[] interfaces) throws
IOException, ClassNotFoundException {
ClassLoader nonPublicLoader = null;
boolean hasNonPublicInterface = false;
// define proxy in class loader of non-public interface(s), if any
Class<?>[] classObjs = new Class<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
Class<?> cl = Class.forName(interfaces[i], false, classLoader);
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
if (hasNonPublicInterface) {
if (nonPublicLoader != cl.getClassLoader()) {
throw new IllegalAccessError(
"conflicting non-public interface class loaders");
}
} else {
nonPublicLoader = cl.getClassLoader();
hasNonPublicInterface = true;
}
}
classObjs[i] = cl;
}
try {
return Proxy.getProxyClass(hasNonPublicInterface ?
nonPublicLoader : classLoader, classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
protected Constructor<?> getResultSetConstructor() throws NoSuchMethodException {
if (resultSetConstructor == null) {
Class<?> proxyClass = Proxy.getProxyClass(StatementDecoratorInterceptor.class.getClassLoader(),
new Class[] { ResultSet.class });
resultSetConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
}
return resultSetConstructor;
}
/**
* Creates and caches a {@link java.lang.reflect.Constructor} used to instantiate the proxy object.
* We cache this, since the creation of a constructor is fairly slow.
* @param xa Use a XA connection
* @return constructor used to instantiate the wrapper object
* @throws NoSuchMethodException Failed to get a constructor
*/
public Constructor<?> getProxyConstructor(boolean xa) throws NoSuchMethodException {
//cache the constructor
if (proxyClassConstructor == null ) {
Class<?> proxyClass = xa ?
Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class, javax.sql.XAConnection.class}) :
Proxy.getProxyClass(ConnectionPool.class.getClassLoader(), new Class[] {java.sql.Connection.class,javax.sql.PooledConnection.class});
proxyClassConstructor = proxyClass.getConstructor(new Class[] { InvocationHandler.class });
}
return proxyClassConstructor;
}
@Override
protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
if (classLoader != null) {
ClassLoader nonPublicLoader = null;
boolean hasNonPublicInterface = false;
// define proxy in class loader of non-public interface(s), if any
Class<?>[] classObjs = new Class<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
Class<?> cl = Class.forName(interfaces[i], false, classLoader);
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
if (hasNonPublicInterface) {
if (nonPublicLoader != cl.getClassLoader()) {
throw new IllegalAccessError(
"conflicting non-public interface class loaders");
}
} else {
nonPublicLoader = cl.getClassLoader();
hasNonPublicInterface = true;
}
}
classObjs[i] = cl;
}
try {
return Proxy.getProxyClass(
hasNonPublicInterface ? nonPublicLoader : classLoader, classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
return super.resolveProxyClass(interfaces);
}
/**
* Generate proxy object array of the given size.
*/
Proxy[] genProxies(int size) throws Exception {
Class proxyClass =
Proxy.getProxyClass(DummyInterface.class.getClassLoader(),
new Class[] { DummyInterface.class });
Constructor proxyCons =
proxyClass.getConstructor(new Class[] { InvocationHandler.class });
Object[] consArgs = new Object[] { new DummyHandler() };
Proxy[] proxies = new Proxy[size];
for (int i = 0; i < size; i++)
proxies[i] = (Proxy) proxyCons.newInstance(consArgs);
return proxies;
}
/**
* Define a proxy class in the given class loader. The proxy
* class will implement the given interfaces Classes.
*/
private static Class<?> loadProxyClass(ClassLoader loader, Class<?>[] interfaces)
throws ClassNotFoundException
{
try {
return Proxy.getProxyClass(loader, interfaces);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(
"error creating dynamic proxy class", e);
}
}
protected Class<?> resolveProxyClass(String[] interfaces) throws
IOException, ClassNotFoundException {
ClassLoader nonPublicLoader = null;
boolean hasNonPublicInterface = false;
// define proxy in class loader of non-public interface(s), if any
Class<?>[] classObjs = new Class<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
Class<?> cl = Class.forName(interfaces[i], false, classLoader);
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
if (hasNonPublicInterface) {
if (nonPublicLoader != cl.getClassLoader()) {
throw new IllegalAccessError(
"conflicting non-public interface class loaders");
}
} else {
nonPublicLoader = cl.getClassLoader();
hasNonPublicInterface = true;
}
}
classObjs[i] = cl;
}
try {
return Proxy.getProxyClass(hasNonPublicInterface ?
nonPublicLoader : classLoader, classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
public static void main(String[] args) throws Exception {
ClassLoader l = new Loader();
Class i = Class.forName(CLASS_NAME, false, l);
System.out.println(i);
Class p = Proxy.getProxyClass(i.getClassLoader(), new Class[] { i });
System.out.println(p);
}
public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) {
return Proxy.getProxyClass(cl, ifaces);
}
protected Class<?> resolveProxyClass(String[] interfaces)
throws IOException, ClassNotFoundException {
Set<String> s = new HashSet<String>(interfaces.length);
for (int i = 0; i < interfaces.length; i++) {
s.add(interfaces[i]);
}
ClassLoader classLoader = map.get(s);
if (classLoader == null) {
return super.resolveProxyClass(interfaces);
}
// The code below is mostly copied from the superclass.
ClassLoader nonPublicLoader = null;
boolean hasNonPublicInterface = false;
// define proxy in class loader of non-public interface(s), if any
Class[] classObjs = new Class[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
Class cl = Class.forName(interfaces[i], false, classLoader);
if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
if (hasNonPublicInterface) {
if (nonPublicLoader != cl.getClassLoader()) {
throw new IllegalAccessError(
"conflicting non-public interface class loaders");
}
} else {
nonPublicLoader = cl.getClassLoader();
hasNonPublicInterface = true;
}
}
classObjs[i] = cl;
}
try {
return Proxy.getProxyClass(hasNonPublicInterface ?
nonPublicLoader : classLoader,
classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
/**
* Create a composite interface Class for the given interfaces,
* implementing the given interfaces in one single Class.
* <p>This implementation builds a JDK proxy class for the given interfaces.
* @param interfaces the interfaces to merge
* @param classLoader the ClassLoader to create the composite Class in
* @return the merged interface as Class
* @throws IllegalArgumentException if the specified interfaces expose
* conflicting method signatures (or a similar constraint is violated)
* @see java.lang.reflect.Proxy#getProxyClass
*/
@SuppressWarnings("deprecation")
public static Class<?> createCompositeInterface(Class<?>[] interfaces, @Nullable ClassLoader classLoader) {
Assert.notEmpty(interfaces, "Interfaces must not be empty");
return Proxy.getProxyClass(classLoader, interfaces);
}