001package org.javasimon.proxy; 002 003import java.lang.reflect.InvocationHandler; 004import java.lang.reflect.Method; 005import java.lang.reflect.Proxy; 006 007/** 008 * Produces proxy that wrap and existing class using {@link java.lang.reflect.Proxy} class. 009 * This class is used to do lightweight AOP. 010 * 011 * @param <T> Type of the wrapped class 012 * @author gerald 013 */ 014public class DelegatingProxyFactory<T> implements InvocationHandler, Delegating<T> { 015 016 /** Wrapped class and concrete implementation. */ 017 private final T delegate; 018 019 /** 020 * Main constructor. 021 * 022 * @param delegate Wrapped class and concrete implementation 023 */ 024 public DelegatingProxyFactory(T delegate) { 025 super(); 026 this.delegate = delegate; 027 } 028 029 public final Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 030 return invoke(new DelegatingMethodInvocation<>(delegate, proxy, method, args)); 031 } 032 033 /** 034 * Method to override in child classes. 035 * 036 * @param delegatingMethodInvocation Method invocation (arguments, method name, etc.) 037 * @return Method invocation results 038 * @throws Throwable Method invocation raised exception 039 */ 040 protected Object invoke(DelegatingMethodInvocation<T> delegatingMethodInvocation) throws Throwable { 041 return delegatingMethodInvocation.proceed(); 042 } 043 044 /** Return Wrapped class and concrete implementation. */ 045 public T getDelegate() { 046 return delegate; 047 } 048 049 /** 050 * Create a proxy using given classloader and interfaces 051 * 052 * @param classLoader Class loader 053 * @param interfaces Interfaces to implement 054 * @return Proxy 055 */ 056 public Object newProxy(ClassLoader classLoader, Class<?>... interfaces) { 057 return Proxy.newProxyInstance(classLoader, interfaces, this); 058 } 059 060 /** 061 * Create a proxy using given classloader and interfaces. 062 * Current thread classloader is used as a default. 063 * 064 * @param interfaces Interfaces to implement 065 * @return Proxy 066 */ 067 public Object newProxy(Class<?>... interfaces) { 068 return newProxy(Thread.currentThread().getContextClassLoader(), interfaces); 069 } 070 071 /** 072 * Create a proxy using given classloader and interfaces. 073 * 074 * @param interfaces Interface to implement 075 * @return proxy 076 */ 077 public <X> X newProxy(Class<X> interfaces) { 078 return (X) newProxy(new Class[] {interfaces}); 079 } 080}