How to get 'proxied' object from an existing dynamic proxy - java

Is there an some API like Proxy.getProxiedObject(), that will return the original object of a dynamic proxy? I would like, for example, to invoke equals on the proxied objects, rather than on the dynamic proxies themselves, like in the following example:
public class ProxyTest implements InvocationHandler {
public static Object createProxy(Object target) {
Class<? extends Object> clazz = target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new ProxyTest());
}
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
// PROXIED OBJECTS COMPARISON - DESIRED
// return Proxy.getProxiedObject(proxy).equals(Proxy.getProxiedObject(args[0]));
// DYNAMIC PROXIES COMPARISON - UNDESIRED
// return proxy.equals(args[0]);
return null;
}
public static void main(String[] args) {
Object proxied = createProxy(new Object());
System.out.println(proxied.equals(proxied));
}
}

I don't think there's any API available for this; but I built a workaround this using the API that retrieves the InvocationHandler from any Proxy object, and the one that tests where or not a Class is a Proxy class:
InvocationHandler getInvocationHandler(Object proxy) throws IllegalArgumentException
boolean isProxyClass(Class<?> cl)
Using these I created an abstract extension of InvocationHandler to keep a reference to the object being proxied, with a static utility to retrieve the proxied object out of any potential Proxy object, and a factory utility for creating Proxys using the target object:
public abstract class ProxiedSavedInvocationHandler implements InvocationHandler {
public static Object getProxied(Object proxy) {
if (!Proxy.isProxyClass(proxy.getClass()))
return null;
InvocationHandler handler = Proxy.getInvocationHandler(proxy);
return (handler instanceof ProxiedSavedInvocationHandler) ?
((ProxiedSavedInvocationHandler)handler).proxied : null;
}
protected final Object proxied;
public ProxiedSavedInvocationHandler(Object proxied) {
this.proxied = proxied;
}
public Object getProxied() {
return proxied;
}
public Object createProxy() {
Class<? extends Object> clazz = proxied.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
}
Then I just used the newly created class like this:
class MyProxiedSavedInvocationHandler extends ProxiedSavedInvocationHandler {
...
}
ProxiedSavedInvocationHandler handler = new MyProxiedSavedInvocationHandler(target);
Object proxy = handler.createProxy();
// DESIRED API THROUGH STATIC UTILIY
Object proxied1 = ProxiedSavedInvocationHandler.getProxied(proxy);
// DESIRED API THROUGH INSTANCE UTILIY
Object proxied2 = handler.getProxied();
The only dependency on this solution is having the ProxiedSavedInvocationHandler utility class where all the logic and new APIs are located. This class can be extended even to include APIs to delegate behavior to other InvocationHandlers transparently; but the minimum required is there.
The following is a full working example application of this solution:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
static class MyProxiedSavedInvocationHandler extends ProxiedSavedInvocationHandler {
public MyProxiedSavedInvocationHandler(Object proxied) {
super(proxied);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
if (!method.getName().equals("equals"))
return method.invoke(proxied, args);
Object other = ProxiedSavedInvocationHandler.getProxied(args[0]);
System.out.println("====");
System.out.println("\tRunning 'equals' inside proxy with:");
System.out.println("\tthis: " + proxied);
System.out.println("\tother: " + other);
System.out.println("====");
return proxied.equals(other);
}
}
static abstract class ProxiedSavedInvocationHandler implements InvocationHandler {
public static Object getProxied(Object proxy) {
if (!Proxy.isProxyClass(proxy.getClass()))
return null;
InvocationHandler handler = Proxy.getInvocationHandler(proxy);
return (handler instanceof ProxiedSavedInvocationHandler) ?
((ProxiedSavedInvocationHandler)handler).proxied : null;
}
protected final Object proxied;
public ProxiedSavedInvocationHandler(Object proxied) {
this.proxied = proxied;
}
public Object getProxied() {
return proxied;
}
public Object createProxy() {
Class<? extends Object> clazz = proxied.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
}
// TO TEST EDGE SCENARIONS
private static Object createProxy(Class<? extends Object> clazz, InvocationHandler handler) {
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), handler);
}
// MAIN
public static void main(String[] args) {
// EDGE SCENARIOS
Object proxiedFromNotEnhancedProxy =
ProxiedSavedInvocationHandler.getProxied(createProxy(Object.class, (p, m, a) -> null));
Object proxiedFromNotAProxy =
ProxiedSavedInvocationHandler.getProxied(new Object());
System.out.println("proxied from NOT ENHANCED PROXY: " + proxiedFromNotEnhancedProxy);
System.out.println("proxied from NOT A PROXY: " + proxiedFromNotAProxy);
System.out.println();
// FUNCTIONALITY DESIRED
Object target = new Object();
ProxiedSavedInvocationHandler handler = new MyProxiedSavedInvocationHandler(target);
Object proxy = handler.createProxy();
Object proxied1 = ProxiedSavedInvocationHandler.getProxied(proxy);
Object proxied2 = handler.getProxied();
System.out.println("target: " + target);
System.out.println("proxied1: " + proxied1);
System.out.println("target == proxied1: " + (target == proxied1));
System.out.println("proxy.equals(proxy): " + proxy.equals(proxy));
}
}
Complete code on GitHub

Related

Spring AOP Target Object Aspect not being called when target object is accessed via reflection

I currently have Spring AOP defining an aspect for logging(Logging Aspect) on a Spring Bean (Target Implementation). When I access the method normally (Regular Access) My Implementation runs and I receive logs. However, when I access my implementation via reflection (Reflection Access) My implementation runs, but I do not receive any logging. I would like to understand why this is and how I can get my reflection based access pattern to get logs. See Reference picture
Full example: (Note the reflection call actually comes from the parent class)
Parent Class (with reflection call)
public class EventValidationHandler {
private List<Method> aggregateMethods;
public EventValidationHandler() {
aggregateMethods = getMethodsAnnotatedWithAggregateEventHandler(this.getClass());
}
public boolean validateEvent(DomainEvent event) throws Exception {
Class clazz = event.getClass();
for(Method method : aggregateMethods) {
for(Class aClass : method.getParameterTypes()) {
if(clazz.equals(aClass)) {
Object response = method.invoke(this, event);
return (Boolean) response;
}
}
}
throw new NoSuchMethodError("Unable to locate event validator method for event type: " + event.getClass().getSimpleName() + ". Please confirm method is annotated with #" + EventValidator.class.getSimpleName());
}
private static List<Method> getMethodsAnnotatedWithAggregateEventHandler(final Class<?> type) {
final List<Method> methods = new ArrayList<>();
final List<Method> allMethods = new ArrayList<>(Arrays.asList(type.getDeclaredMethods()));
for (final Method method : allMethods) {
if (method.isAnnotationPresent(EventValidator.class)) {
methods.add(method);
}
}
return methods;
}
}
Implementation
#Component
#AllArgsConstructor
public class MyEventValidator extends EventValidationHandler {
private AggregateRepository aggregateRepository;
#EventValidator
public boolean isValid(CreateProfileEvent event) {
if(aggregateRepository.findOne(event.getEmployeeId()) == null) {
return true;
}
return false;
}
#EventValidator
public boolean isValid(ChangePhoneNumberEvent event) {
if(aggregateRepository.findOne(event.getEmployeeId()) != null) {
return true;
}
return false;
}
}
Logging Aspect
#Aspect
#Component
public class MyEventValidatorLoggingAspect {
public static Logger log = LoggerFactory.getLogger(MyEventValidator.class);
#Pointcut("execution(* com.mcf7.eventsourcing.test.data.events.MyEventValidator.isValid(com.mcf7.eventsourcing.test.data.events.CreateProfileEvent))")
private void createProfile() {}
#Before("createProfile()")
public void logHere(JoinPoint joinPoint) {
log.info("super cool log of create profile");
}
}

How to implement factory pattern with generics in Java?

I have a generic interface Handler
public interface Handler<T> {
void handle(T obj);
}
I can have n implementations of this interface. Let's say I have following 2 implementations for now. One which handles String objects and another handles Date
public class StringHandler implements Handler<String> {
#Override
public void handle(String str) {
System.out.println(str);
}
}
public class DateHandler implements Handler<Date> {
#Override
public void handle(Date date) {
System.out.println(date);
}
}
I want to write a factory which will return handler instances based on the class type. Something like this :
class HandlerFactory {
public <T> Handler<T> getHandler(Class<T> clazz) {
if (clazz == String.class) return new StringHandler();
if (clazz == Date.class) return new DateHandler();
}
}
I get following error in this factory :
Type mismatch: cannot convert from StringHandler to Handler<T>
How to fix this?
SIMPLE SOLUTION
You could save your mappings Class<T> -> Handler<T> in a Map. Something like:
Map<Class<T>, Handler<T>> registry = new HashMap<>();
public void registerHandler(Class<T> dataType, Class<? extends Handler> handlerType) {
registry.put(dataType, handlerType);
}
public <T> Handler<T> getHandler(Class<T> clazz) {
return registry.get(clazz).newInstance();
}
In some place, initialize handlers (could be in the factory itself):
factory.registerHandler(String.class, StringHandler.class);
factory.registerHandler(Date.class, DateHandler.class);
And in another place, you create and use them:
Handler<String> stringhandler = factory.getHandler(String.class);
Handler<Date> dateHandler = factory.getHandler(Date.class);
MORE COMPLEX SOLUTION
You can "scan" classes using reflection and, instead of register manually the mappings Class<T> -> Handler<T>, do it using reflection.
for (Class<? extends Handler> handlerType : getHandlerClasses()) {
Type[] implementedInterfaces = handlerType.getGenericInterfaces();
ParameterizedType eventHandlerInterface = (ParameterizedType) implementedInterfaces[0];
Type[] types = eventHandlerInterface.getActualTypeArguments();
Class dataType = (Class) types[0]; // <--String or Date, in your case
factory.registerHandler(dataType, handlerType);
}
Then, you create and use them like above:
Handler<String> stringhandler = factory.getHandler(String.class);
Handler<Date> dateHandler = factory.getHandler(Date.class);
To implement getHandlerClasses(), look at this to scan all classes in your jar. For each class, you have to check if it is a Handler:
if (Handler.class.isAssignableFrom(scanningClazz) //implements Handler
&& scanningClazz.getName() != Handler.class.getName()) //it is not Handler.class itself
{
//is a handler!
}
Hope it helps!
Your problem is that the compiler cannot make the leap to the fact thet the type of the result is correct.
To help the compiler you can make the factory delegate the construction. Although this looks strange and unwieldly it does manage to properly maintain type safety without sacrifices such as casting or using ? or raw types.
public interface Handler<T> {
void handle(T obj);
}
public static class StringHandler implements Handler<String> {
#Override
public void handle(String str) {
System.out.println(str);
}
}
public static class DateHandler implements Handler<Date> {
#Override
public void handle(Date date) {
System.out.println(date);
}
}
static class HandlerFactory {
enum ValidHandler {
String {
#Override
Handler<String> make() {
return new StringHandler();
}
},
Date {
#Override
Handler<Date> make() {
return new DateHandler();
}
};
abstract <T> Handler<T> make();
}
public <T> Handler<T> getHandler(Class<T> clazz) {
if (clazz == String.class) {
return ValidHandler.String.make();
}
if (clazz == Date.class) {
return ValidHandler.Date.make();
}
return null;
}
}
public void test() {
HandlerFactory factory = new HandlerFactory();
Handler<String> stringHandler = factory.getHandler(String.class);
Handler<Date> dateHandler = factory.getHandler(Date.class);
}
The whole point of using a generic type is to share the implementation. If the n implementation of your Handler interface are so different that they can't be shared, then I don't think there is any reason to use define that generic interface at the first place. You'd rather just have StringHandler and DateHandler as top level classes.
On the other hand, if the implementation can be shared, as is the case of your example, then the factory works naturally:
public class Main {
static public interface Handler<T> {
void handle(T obj);
}
static public class PrintHandler<T> implements Handler<T> {
#Override
public void handle(T obj) {
System.out.println(obj);
}
}
static class HandlerFactory {
public static <T> Handler<T> getHandler() {
return new PrintHandler<T>();
}
}
public static void main(String[] args) {
Handler<String> stringHandler = HandlerFactory.getHandler();
Handler<Date> dateHandler = HandlerFactory.getHandler();
stringHandler.handle("TEST");
dateHandler.handle(new Date());
}
}
You can use something like:
class HandlerFactory {
public <T> Handler<T> getHandler(Class<T> clazz) {
if (clazz.equals(String.class)) return (Handler<T>) new StringHandler();
if (clazz.equals(Date.class)) return (Handler<T>) new DateHandler();
return null;
}
}
T is generic and the compiler can't map that at compile time. Also it is safer to use .equals instead of ==.
Define an interface for creating an object, but let subclasses decide which class to instantiate.
Factory method lets a class defer instantiation to subclasses.
Define generic abstract class
public abstract class Factory<T> {
public abstract T instantiate(Supplier<? extends T> supplier);
}
And a generic supplier
public class SupplierFactory<T> extends Factory<T> {
#Override
public T instantiate(Supplier<? extends T> supplier) {
return supplier.get();
}
}
Then an implementation needs to have concrete classes to implement the base interface and a main class to show class defer instantiation . i.e
The base interface (desired interface of the requirement)
public interface BaseInterface {
void doAction();
}
The first concrete class
public class Alpha implements BaseInterface {
#Override
public void doAction() {
System.out.println("The Alpha executed");
}
}
And the second one
public class Beta implements BaseInterface {
#Override
public void doAction() {
System.out.println("The Beta executed");
}
}
The main
public class Main {
public static void main(String[] args) {
Factory<BaseInterface> secondFactory = new SupplierFactory<>();
secondFactory.instantiate(Beta::new).doAction();
secondFactory.instantiate(Alpha::new).doAction();
}
}
Basically you can do:
public Handler getHandler( Class clazz ){
if( clazz == String.class ) return new StringHandler();
if( clazz == Date.class ) return new DateHandler();
return null;
}
public static void main( String[] args ){
HandlerFactory handlerFactory = new HandlerFactory();
StringHandler handler = ( StringHandler )handlerFactory.getHandler( String.class );
handler.handle( "TEST" );
DateHandler handler2 = ( DateHandler )handlerFactory.getHandler( Date.class );
handler2.handle( new Date() );
}
Output:
TEST
Tue Dec 15 15:31:00 CET 2015
But instead writing two different methods to get handlers separately always is a better way.
I edited your code and allowed Eclipse to "fix" the errors and it came up with this.
public Handler<?> getHandler(Class<?> clazz) {
if (clazz == String.class)
return new StringHandler();
if (clazz == Date.class)
return new DateHandler();
return null;
}
Yout HandlerFactory don't know about T. Use your factory like below-
public class HandlerFactory {
public Handler<?> getHandler(Class<?> clazz) {
if (clazz == String.class) {
return new StringHandler();
}
if (clazz == Date.class) {
return new DateHandler();
}
return null;
}
}

JNA Objective-C (Rococoa) Calendar Callback

I want to access the Objective-C EKEventStore in Java via Rococoa. The API specifies a callback to get notified when the user accepts the calendar access prompt, which works perfectly in pure Objective-C.
Native.loadLibrary("EventKit", EventKitLibrary.class);
EKEventStore store = EKEventStore.CLASS.alloc();
store.init();
//store = store.initWithAccessToEntityTypes(EKEntityType.EKEntityTypeEvent); // no notification
EKEventStoreRequestAccessCompletionHandler handler = new EKEventStoreRequestAccessCompletionHandler() {
#Override
public void invoke(boolean granted, Pointer error) {
System.out.println("Access: " + granted);
NSArray calArray = store.calendarsForEntityType(EKEntityType.EKEntityTypeEvent);
for (int i = 0; i < calArray.count(); i++) {
NSObject calObject = calArray.objectAtIndex(i);
EKCalendar osxcal = Rococoa.cast(calObject, EKCalendar.class);
System.out.println(osxcal.title().toString());
}
}
};
ObjCObject object = Rococoa.proxy(handler); // get Objective C Callback Object to send
store.requestAccessToEntityType_completion(EKEntityType.EKEntityTypeEvent, object.id());
try {
Thread.sleep(10000); // wait for the access prompt
} catch (InterruptedException ex) {
}
// random object access to save instances from gc
System.out.println(handler.toString());
System.out.println(store.id());
System.out.println(object.id());
The Library
public interface EventKitLibrary extends Library {
public static EventKitLibrary INSTANCE = (EventKitLibrary) Native.loadLibrary("EventKit", EventKitLibrary.class);
}
The Mapped Classes
public abstract class EKEventStore extends NSObject {
public static final _Class CLASS = Rococoa.createClass("EKEventStore", _Class.class);
public interface _Class extends ObjCClass {
public abstract EKEventStore alloc();
}
public static interface EKEntityType {
public static final int EKEntityTypeEvent = 0;
public static final int EKEntityTypeReminder = 1;
};
public static interface EKEntityMask {
public static final int EKEntityMaskEvent = (1 << EKEntityType.EKEntityTypeEvent);
public static final int EKEntityMaskReminder = (1 << EKEntityType.EKEntityTypeReminder);
};
public abstract EKEventStore initWithAccessToEntityTypes(int EKEntityMask);
public abstract EKEventStore init();
public abstract void requestAccessToEntityType_completion(int EKEntityType, ID handler);
interface EKEventStoreRequestAccessCompletionHandler {
void invoke(boolean granted, Pointer error);
}
public abstract NSArray calendarsForEntityType(int EKEntityType);
}
public abstract class EKCalendar extends NSObject {
public static final _Class CLASS = Rococoa.createClass("EKCalendar", _Class.class);
public static interface _Class extends ObjCClass {
public NSObject alloc();
}
public abstract NSString title();
}
I only get an IllegalArgumentException for a missing type conversion of the NSError parameter. Am I doing something wrong, or should I implement a TypeConverter? And if, how should I do that?
EDIT:
Now I am using Pointer instead of NSError as parameter for the callback function, and I get the following JVM-Crash.
EDIT2:
Now I am using the Rococoa.proxy(handler) function for the callback like in the Rococoa Library. The input prompt appears, but the callback function doesn't get called. I think my callback initialization is still wrong.
Generally, a TypeMapper is implemented like this which converts a Pointer native type into some other Java type:
class NSErrorTypeMapper extends DefaultTypeMapper {
public NSErrorTypeMapper() {
TypeConverter tc = new TypeConverter() {
public Object toNative(Object value, ToNativeContext ctxt) {
Pointer p = // convert your NSError "value" into a Pointer
return p;
}
public Object fromNative(Object value, FromNativeContext ctxt) {
Pointer p = (Pointer)value;
Object object = // convert the pointer into an NSError object
return object;
}
public class nativeType() {
return Pointer.class;
}
};
addToNativeConverter(NSError.class, tc);
addFromNativeConverter(NSError.class, tc);
}
}

Factory objects creator with generics

I want to do a factory pattern in java with generics. My code is:
The interface:
public abstract class Factory<T> {
public abstract T create();
}
FactoryA class:
public class FactoryA extends Factory<FactoryA> {
public FactoryA() {
}
public FactoryA create() {
return new FactoryA();
}
}
FactoryB class:
public class FactoryB extends Factory<FactoryB> {
public FactoryB() {
}
public FactoryB create() {
return new FactoryB();
}
}
The main class:
public class FactoryCreator {
public static <T> T createFactory() {
Factory<T> t = ?; // is that right way?
return t.create();
}
public static void main(String[] args) {
FactoryA factoryA = FactoryCreator.createFactory();
FactoryB factoryB = FactoryCreator.createFactory();
}
}
The question, what Factory t = need to be equal, or is there any other way?
Not really sure what you're trying to achieve, but this might help;
public interface Factory<T>
{
public T create(String type);
public T create(String type, Object arg);
public T create(String type, Object[] args);
}
And then have a class implement that factory interface, like this;
public class TemplateFactory<T> implements Factory {
#Override
public T create(String type) throws IllegalArgumentException
{
return create(type, null);
}
#Override
public T create(String type, Object arg) throws IllegalArgumentException
{
// Convert to array of 1 element
Object[] arguments = new Object[1];
arguments[0] = arg;
return create(type, arguments);
}
#Override
public T create(String type, Object[] args) throws IllegalArgumentException
{
// Create array for all the parameters
Class<?> params[] = (args != null) ? new Class<?>[args.length] : new Class<?>[0];
if(args != null)
{
// Adding the types of the arguments
for(int i = 0; i < args.length; ++i)
params[i] = (args[i] != null) ? args[i].getClass() : null;
}
try
{
// Create a class variable
Class classLoader = Class.forName(type);
// Find the right constructor
Constructor co;
if(params.length > 0)
co = classLoader.getConstructor(params);
else
co = classLoader.getConstructor();
// Instantiate the class with the given arguments
T newObject = (T)co.newInstance(args);
return newObject;
}
catch(Exception e)
{
throw new IllegalArgumentException(e.toString());
}
}
}
And then use it like this (using some imaginary strategy-classes as an example):
TemplateFactory<StrategyInterface> factory;
factory = new TemplateFactory<>();
factory.create("packageName.StrategyA");
factory.create("packageName.StrategyB");
factory.create("packageName.StrategyC");
The strategy classes (A, B and C) would implement the StrategyInterface-class in this example.
Something like this might work:
public static <T extends Factory> T createFactory(Class<T> clazz) {
try {
t = clazz.newInstance();
return t.create();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
...
FactoryA factoryA = FactoryCreator.createFactory(FactoryA.class);
alternatively, without parameters. But then you need two methods.
public static FactoryA createFactoryA() {
return new FactoryA().create();
}
...
FactoryA factoryA = FactoryCreator.createFactoryA();
Since the Generic types are erased at runtime you have to supply the Class parameter so that the runtime knows what class you are talking about.

Why does JDK dynamic Proxy only work with Interfaces?

The JDK Proxy class only accepts interfaces in the factory method newProxyInstance().
Is there a workaround available, or alternative implementations?
The use cases are limited if I have to extract methods to an interface in order to enable them for use with a proxy. I would like to wrap them to apply annotation based actions during runtime.
public static <T> T getProxy(T obj) {
InvocationHandler ih = new InjectProxy( obj );
ClassLoader classLoader = InjectProxy.class.getClassLoader();
return (T) Proxy.newProxyInstance( classLoader, obj.getClass().getInterfaces(), ih );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
You can use cglib like this:
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class AbstractFactory {
#SuppressWarnings("unchecked")
public static <A> A createDefaultImplementation(Class<A> abstractClass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(abstractClass);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if (!Modifier.isAbstract(method.getModifiers())) {
return methodProxy.invokeSuper(proxy, args);
} else {
Class type = method.getReturnType();
if (type.isPrimitive() && !void.class.equals(type)) {
return Array.get(Array.newInstance(type, 1), 0);
} else {
return null;
}
}
}
});
return (A) enhancer.create();
}
#SuppressWarnings("unchecked")
public static <A> A createDefaultImplementation(String className) throws ClassNotFoundException{
return (A) createDefaultImplementation(Class.forName(className));
}
}
This for example lets you build abstract classes with a default implementation method. But you can change the enhancer to what ever you want.
Is there a workaround available..?
Yeah. There is. Extract interface from existing classes.
upd
If you need it for some specific classes, you can write smt like
//interface that already exists
public interface IDomain {
String foo();
}
//your class
public class Domain implements IDomain{
public String foo(){
return "domain foo";
}
//method that doesn't placed in IDomain
public String bar(){
return "domain bar";
}
}
//So you need create new interface with bar()
//it can extend IDomain
public interface ExtendedIDomain extends IDomain {
public String bar();
}
//than your wrapper factory will be like this
public class Proxifier {
public static ExtendedIDomain getProxy(Domain obj) {
InvocationHandler ih = new InjectProxy( obj );
ClassLoader classLoader = InjectProxy.class.getClassLoader();
return (ExtendedIDomain) Proxy.newProxyInstance( classLoader, new Class[]{ExtendedIDomain.class}, ih );
}
static class InjectProxy implements InvocationHandler {
private final Domain domain;
private InjectProxy(Domain domain){
this.domain = domain;
}
public String invoke(Object proxy, Method method, Object[] args) throws Throwable{
for(Method m : domain.getClass().getMethods()){
//TODO: check signature(name, args etc) or implement some logic with annotations
if(m.getName().equals(method.getName())){
return "wrapped " + m.invoke(domain, args);
}
}
throw new IllegalArgumentException();
}
}
}
//test
public static void main(String[] args) {
ExtendedIDomain d = Proxifier.getProxy(new Domain());
System.out.println(d.foo());
System.out.println(d.bar());
}
If you need some "universal" stuff you should use AOP as #Peter Lawrey allready said.
or alternative implementations
You can use cglib.
Similar posts on alternatives to cglib : Are there alternatives to cglib?

Categories

Resources