These sound like cross cutting concerns. Generally this is where AOP comes into play.

Dynamic proxies are one tool in the AOP toolbox however they aren't enough. You can use compiler technologies such as ApspectJ or JBoss's
AOPC; however, greater flexibility (and simplicity) can be achieved through the use of classloader bytecode manipulation.


AOP (compiler or classloader based) allows you to:

1. do dependency injection without special constructors and mutators (aka setters)
2. intercept state changes (even with private class members) and even manipulate state changes (for instance if its set to null then return empty string).
3. intercept method calls (incomming and outgoing) and even manipulate arguments and return values
4. intercept JDK 5 attributes (@transaction type="Required" public void transferMoney(Account a, Account b, double amount);
5. intercept only on a particular call stack (meaning intercept the call on transferMoney only if it is called from the transferRealEstate method)
6. intercept constructors
7. dynamically change the level of instrumentation
8. apply interception per VM, class, instance, method, per call
9. FORCE a class to implement an interface that it did not previously and even supply the implementation of that method.


Dynamic Proxies

1. ONLY allow method call interception on INTERFACE methods.

A particular nasty weakness of dynamic proxies can be seen by creating a Stateless Session Bean.

BankingBeanRemote extends EJBStuff {

public void transferMoney(AccountVO from, AccountVO to, double amount) throws RemoteException;
public void withdrawMoney(AccountVO account, double amount) throws RemoteException;
public void depositMoney(AccountVO account, double amount) throws RemoteException;
public void printStatement(StatementDetails details) throws RemoteException;
}


Say that trans, withdraw and deposit all have "Required" in their assembly descriptor. Say printStatement has RequiresNew.

If within the BankingBean class you call printstatement from transfer money (directly) then it WILL NOT actually get a new transaction!
Why? You MUST go through the interface ( ((BankingBeanRemote)ejbContext.getEnterpriseObject()).printStatement(details) ) or the instrumentation
is not added.


You also must use "setter" based or consturctor-based dependency injection. This leads to the necessity of ctx.lookup calls littering your code to "pull" from
the environment or a lot of XML foo.


anyhow check this out:  http://www.jboss.org/wiki/Wiki.jsp?page=JBossAOP

AOP is primarily a workaround for Java having neither a language meta-model nor a multiple inheritence.

-Andy



Christopher L Merrill wrote:

I'm looking for a technique or pattern to solve the following problem:

I have a class (TheClass) which needs to implement multiple interfaces (iA,
iB and iC). Each has a default implementation which is sufficient for my
needs (AImpl, BImpl and CImpl). In C++, you would use multiple inheritance
to solve this problem - inheriting from all three default implementations
in order to inherit all the default behavior. Of course, this is not
possible in Java (and frankly, I don't miss the complexity of multiple
inheritance).


In the past, I simply implement the interface and pass on method
calls to an aggregated class (e.g. AImpl).  It's simple, but ugly.

I think this could be done with a dynamic proxy, but I'm concerned about
the performance of the heavy use of reflection. Some parts of our application
are extremely performance-sensitive. In my case, it is a compile-time
problem -- no run-time variability is required (in terms of the interfaces
implemented). So using reflection to direct every method call seems
like overkill.


From a language standpoint, it seems to me that some way of combining
the "implements" clause with a contained (aggregated) member would be
the ideal way to solve the problem.  I think of it as
"hyper-aggregation".  For example:

class TheClass implements iA, iB, iC
    {
    AImpl _myvarA provides iA = new AImpl();
    AImpl _myvarB provides iB = new BImpl();
    AImpl _myvarC provides iV = new CImpl();
    }

Thus, the interface iA of AImpl would be exposed as the implementation
of iA for TheClass.  Ideally, one would be able to override the
implementations of each interface within TheClass, when required.
In essence, it is an automatic usage of a dynamic proxy implemented
by the compiler.  The method-call forwarding would be decided by
the compiler, rather than run-time reflection.

Assuming that I am not the first person to run into the problem (nor
the brightest), I have to ask how others solve this problem?  Is there
some obvious problems with my solution above that has kept something
like this from being added to Java?  I can't be the first person to
have thought of it.


TIA, C




_______________________________________________
Juglist mailing list
[email protected]
http://trijug.org/mailman/listinfo/juglist_trijug.org

Reply via email to