Like service locators, dependency injection containers save you from implementing the same dynamic loading and configuration code over and over in different ways; you can configure your entire application consistently in one place. Unlike service locators, dependency injection containers don't require component dependence on a service locator API which facilitates sharing between teams that may have their own service locators.Read Bob Lee in Getter-based Dependency Injection
Cedric and I chatted last week about his "useless methods" blog and the benefits of getter-based dependency injection over setter or constructor-based injection (a la pico container and Spring). Cedric compares CMP entity beans with theoretical getter-based containers which extend classes at runtime and override getter methods to return injected dependencies. The overridden getters may be bean-style (for easier testing) or abstract (for a cleaner, field free implementation). Such a framework would not require classes to declare setter methods, constructors or fields. Getter injection better enables the container to lazy load dependencies and simplifies injecting different dependencies of the same type.
I implemented a simple proof of concept using dynaop which you can find in the dynaop.aspects.ioc package in the aspects directory in CVS. The API consists of a single class Container. The Container.add() methods configure new components. For each component, you specify an implementation class, an optional ID, and optional constructor arguments. You can look up component instances from the container by type or ID with the Container.get() methods. The container overrides component instances' getter methods. The container first looks for a component with an ID that matches the getter method's name; for example, an abstract method getCustomerDataSource() returns an instance of a component with the ID "customerDataSource". If the container can't find a component with a matching ID, it next looks for the first component that implements the method's return type. Finally, if the container still can't find a match, it does not override the method.
-
Getter-based Dependency Injection (33 messages)
- Posted by: Dion Almaer
- Posted on: May 27 2004 01:29 EDT
You have probably heard of setter, and constructor-based dependency injection. Bob Lee implemented a proof of concept using his dynaop framework, and has written all about it.Threaded Messages (33)
- Dependency injection mania by Mileta Cekovic on May 27 2004 11:07 EDT
- Tapestry properties by Marcus Brito on May 27 2004 12:04 EDT
-
Tapestry properties by Paul Strack on May 27 2004 01:12 EDT
-
There is more than one way to do things... by Andrus Adamchik on May 27 2004 02:57 EDT
-
IoC != Dependency Injection by Rodrigo Jardim on May 27 2004 03:34 EDT
- IoC != Dependency Injection by Bob Lee on May 27 2004 04:27 EDT
- IoC != Dependency Injection by Rafael Forte on May 28 2004 05:35 EDT
-
There is more than one way to do things... by George Coller on May 27 2004 04:58 EDT
- There is more than one way to do things... by Andrus Adamchik on May 27 2004 05:14 EDT
-
IoC != Dependency Injection by Rodrigo Jardim on May 27 2004 03:34 EDT
-
There is more than one way to do things... by Andrus Adamchik on May 27 2004 02:57 EDT
-
Tapestry properties by Paul Strack on May 27 2004 01:12 EDT
- Dependency injection mania by Alessandro Santini on May 27 2004 13:02 EDT
- Dependency injection mania by Bill Burke on May 27 2004 01:55 EDT
- Dependency injection mania by Rod Johnson on May 28 2004 12:32 EDT
- Tapestry properties by Marcus Brito on May 27 2004 12:04 EDT
- circular dependancies? by TOny Xue on May 27 2004 14:18 EDT
- circular dependancies? by Bob Lee on May 27 2004 16:29 EDT
- Getter-based Dependency Injection by Colin Sampaleanu on May 27 2004 17:31 EDT
- Abstract classes? No problem! by Howard Lewis Ship on May 27 2004 18:22 EDT
- Getter-based Dependency Injection by Michal Maczka on May 28 2004 07:56 EDT
- Getter-based Dependency Injection by Bill Burke on May 28 2004 07:52 EDT
- Getter-based Dependency Injection by Michal Maczka on May 28 2004 08:05 EDT
- Getter-based Dependency Injection by Bill Burke on May 28 2004 10:00 EDT
- Getter-based Dependency Injection by Michal Maczka on May 28 2004 08:05 EDT
- Getter^H^H^H^H^H^HField-based Dependency Injection by Emmanuel Pirsch on May 28 2004 09:48 EDT
- Getter^H^H^H^H^H^HField-based Dependency Injection by Michal Maczka on May 28 2004 10:43 EDT
-
Getter^H^H^H^H^H^HField-based Dependency Injection by Bill Burke on May 28 2004 11:40 EDT
- Getter^H^H^H^H^H^HField-based Dependency Injection by Michal Maczka on May 28 2004 02:45 EDT
-
Getter^H^H^H^H^H^HField-based Dependency Injection by Bill Burke on May 28 2004 11:40 EDT
- Getter^H^H^H^H^H^HField-based Dependency Injection by Bob Lee on May 28 2004 11:05 EDT
-
Getter^H^H^H^H^H^HField-based Dependency Injection by Bill Burke on May 28 2004 11:49 EDT
-
Getter^H^H^H^H^H^HField-based Dependency Injection by Bob Lee on May 28 2004 12:11 EDT
-
GetterField-based Dependency Injection by Bill Burke on May 28 2004 01:50 EDT
- GetterField-based Dependency Injection by Bob Lee on May 28 2004 02:56 EDT
-
GetterField-based Dependency Injection by Bill Burke on May 28 2004 01:50 EDT
-
Getter^H^H^H^H^H^HField-based Dependency Injection by Bob Lee on May 28 2004 12:11 EDT
-
Getter^H^H^H^H^H^HField-based Dependency Injection by Bill Burke on May 28 2004 11:49 EDT
- Getter^H^H^H^H^H^HField-based Dependency Injection by Michal Maczka on May 28 2004 10:43 EDT
- how to cache? by Bill Burke on May 28 2004 10:03 EDT
- how to cache? by Bob Lee on May 28 2004 11:02 EDT
-
how to cache? by Bill Burke on May 28 2004 11:43 EDT
- how to cache? by Bob Lee on May 28 2004 12:29 EDT
-
how to cache? by Bill Burke on May 28 2004 11:43 EDT
- how to cache? by Bob Lee on May 28 2004 11:02 EDT
-
Dependency injection mania[ Go to top ]
- Posted by: Mileta Cekovic
- Posted on: May 27 2004 11:07 EDT
- in response to Dion Almaer
Dependency injection mania continues... -
Tapestry properties[ Go to top ]
- Posted by: Marcus Brito
- Posted on: May 27 2004 12:04 EDT
- in response to Mileta Cekovic
This looks a lot like Tapestry's properties. The only difference is that using tapestry, page or component properties are declared in the specification, and their values are not automatically injected from some context. Abstract getters is a good IDEA, and I hope that some mainstream bean container (like Spring) implements this.
Anyway just for reference, here's what I do today with Tapestry:
<page-specification class="com.myco.MyPage">
<property-specification name="myDependency" type="com.myco.MyDependency">
global.appContext.getBean("myDependency")
</property-specification>
</page-specification>
This is actually documented in Spring's documentation, in a dedicated chapter to Tapestry integration. The <property-specification> declares a property for the current page, and the element value is it's initial value. Here, the value is looked up from a Spring context, stored in the application global object.
You can declare only the methods you'll need on the MyPage class: if you'll be getting the property value (most likely), just declare an abstract getter and Tapestry will implement it at runtime. If you need to set the property value (not so likely), just declare an abstract setter and Tapastry will implement it.
I just love this thing. However, I can only use this in Tapestry pages and compenents -- I'd love to do something similar for my business objects. -
Tapestry properties[ Go to top ]
- Posted by: Paul Strack
- Posted on: May 27 2004 13:12 EDT
- in response to Marcus Brito
I don't know ... to my mind, one of the big advantages of IOC/Injection is that it allows for easier out-of-container testing. If you use abstract getters for injection, it means that all of your components must be defined as abstract classes. You won't be able to test them without (a) using your container or (b) defining lots of mock objects.
There are other problems with abstract component classes. If your component class is a concrete class, your compiler will catch mistakes like incorrectly overriding a method in an interface (say, by misspelling the method name). If your components are abstract, you have to keep track of this stuff manually. Also, subclassing your components becomes more complicated (which abstract methods need to be overridden, which one should be left alone?).
Personally, I would rather live with the extra setters in order to get a concrete class. -
There is more than one way to do things...[ Go to top ]
- Posted by: Andrus Adamchik
- Posted on: May 27 2004 14:57 EDT
- in response to Paul Strack
I don't know ... to my mind, one of the big advantages
> of IOC/Injection is that it allows for easier
> out-of-container testing.
Exactly. There is nothing wrong with people experimenting with different ways of using IoC, so this seems like a nice research project. However I prefer having a working object that doesn't require any runtime enhancement to be usable.
Andrus -
IoC != Dependency Injection[ Go to top ]
- Posted by: Rodrigo Jardim
- Posted on: May 27 2004 15:34 EDT
- in response to Andrus Adamchik
Inversion of Control is not the same as Dependency Injection,
whell every type of DI is a kind of IoC, but not every kind of IoC is a type of DI,
lets explain this,
the pattern "template method" is one type of Inversion of Control (which was born in the GoF book if I'm not wrong)
but a template method is not a kind of DI :-)
I think this puts things clearer :-)
EOF :-)
PS.: Portuguese speachers see my Blog: http://www.javablogs.com.br/blogs/page/urubatan -
IoC != Dependency Injection[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 27 2004 16:27 EDT
- in response to Rodrigo Jardim
Inversion of Control is not the same as Dependency Injection,whell every type of DI is a kind of IoC, but not every kind of IoC is a type of DI,lets explain this,the pattern "template method" is one type of Inversion of Control (which was born in the GoF book if I'm not wrong)but a template method is not a kind of DI
Good point. Perhaps I should have called this "Dynamic Templates." -
IoC != Dependency Injection[ Go to top ]
- Posted by: Rafael Forte
- Posted on: May 28 2004 17:35 EDT
- in response to Rodrigo Jardim
I don't think in this way...
The DI pattern is a special case of template method (using inheritance) or strategy (using composition) focused in objects association configuration(oac). This type of *special use* already happens in GoF pattern Factory Method. The Factory Method is a type of Template Method used to create objects.
It is all about callback methods.
<Rodrigo>
the pattern "template method" is one type of Inversion of Control (which was born in the GoF book if I'm not wrong)
but a template method is not a kind of DI :-)
</Rodrigo>
I think the correct sentence is: Template method is a way to implement IoC and DI is a special type of IoC used in oac, such as Factory Method is a type of IoC (maybe implemented using a Template Method).
Regards,
Forte -
There is more than one way to do things...[ Go to top ]
- Posted by: George Coller
- Posted on: May 27 2004 16:58 EDT
- in response to Andrus Adamchik
However I prefer having a working object that doesn't require any runtime enhancement to be usable.Andrus
I don't understand this comment. If the object was so simple that it didn't have any external dependencies then it wouldn't need Dependency Injection or a ServiceLocator. But for objects that do, Dependency Injection seems to have some advantages over ServiceLocator: Easier testing, component reuse, and centralized config. -
There is more than one way to do things...[ Go to top ]
- Posted by: Andrus Adamchik
- Posted on: May 27 2004 17:14 EDT
- in response to George Coller
The comment refers to the way supposed getter injection is implemented. A quote from the original post:
"Cedric compares CMP entity beans with theoretical getter-based containers which extend classes at runtime and override getter methods to return injected dependencies. The overridden getters may be bean-style (for easier testing) or abstract (for a cleaner, field free implementation). Such a framework would not require classes to declare setter methods, constructors or fields. Getter injection better enables the container to lazy load dependencies and simplifies injecting different dependencies of the same type."
The classes written specifically for the "getter injection" container will be unusable outside of this container, as they there is no *Java* way to initialize them. This is definitely a step back from say Spring, and among other things impedes unit testing as pointed out in the parent post.
But then again - nothing would prevent developers from creating setters, even if they are not required by the framework. So I guess there is a way around.
Andrus -
Dependency injection mania[ Go to top ]
- Posted by: Alessandro Santini
- Posted on: May 27 2004 13:02 EDT
- in response to Mileta Cekovic
Yes ... it is funny to see how quickly the pattern name has changed from "Inversion of Control" to "Dependency Injection" just because Fowler called it that way! (ROFL) -
Dependency injection mania[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 27 2004 13:55 EDT
- in response to Alessandro Santini
Yes ... it is funny to see how quickly the pattern name has changed from "Inversion of Control" to "Dependency Injection" just because Fowler called it that way! (ROFL)
I also find it funny that such a funky name matches such a simple concept (both in implementation, use, and understanding). IMO, one of the reasons IoC is so hot right now because it is (a) easy to understand (b) trivial to implement. So basically anybody with any coding skill can comment on it or implement it.
Anyways, I look forward to reading Bob's blog and hope to come back soon to comment more when I have a chance. -
Dependency injection mania[ Go to top ]
- Posted by: Rod Johnson
- Posted on: May 28 2004 12:32 EDT
- in response to Alessandro Santini
Yes ... it is funny to see how quickly the pattern name has changed from "Inversion of Control" to "Dependency Injection" just because Fowler called it that way! (ROFL)
Before publishing that article, Martin actually consulted the key Pico guys (Aslak and Paul) and myself, as well as some others. Martin originally coined a slightly different name. Although I was at first a bit doubtful about the idea of a renaming, when Aslak and Paul and I talked through it we could see the value of such a name. The 3 of us agreed on the final name "Dependency Injection" and Martin agreed to use that, instead of his original suggestion, in the article.
I regard Dependency Injection as a kind of IoC. The IoC term is still useful.
Regards
Rod -
circular dependancies?[ Go to top ]
- Posted by: TOny Xue
- Posted on: May 27 2004 14:18 EDT
- in response to Dion Almaer
Bob,
How does the "Container" handle the circular dependancies if it exists?
tony
Pleateau.com -
circular dependancies?[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 27 2004 16:29 EDT
- in response to TOny Xue
Bob,How does the "Container" handle the circular dependancies if it exists?tonyPleateau.com
The simple implementation I present doesn't. It creates a new instance for each relationship (i.e. a.getB().getA() != a). A real container could identify circular situations and look up an existing instance. -
Getter-based Dependency Injection[ Go to top ]
- Posted by: Colin Sampaleanu
- Posted on: May 27 2004 17:31 EDT
- in response to Dion Almaer
This is useful mechanism in some cases. Something similar is coming to Spring fairly soon, probably a couple of weeks or so. Rod wrote some code a while ago, but it's waiting for somebody to polish it up a bit.
http://article.gmane.org/gmane.comp.java.springframework.devel/4260/match=prototype+handling+support
What hasn't been mentioned in either Bob's blog entry or this TSS thread (unless I missed it), is that this is a very nice way to handle the situation where a singleton bean coming out of a container, needs to have dependencies populated in it which are themselves not singletons in terms of usage. So if I have a singleton 'PackagingService' coming out of a container, but it needs to work with a non-singleton (also called prototype) service as one of its dependencies, for example an 'EmailService', normal setter dependency injection has issues, because even if the EmailService bean was declared as a prototype in the container, the emailService property on the singleton PackagingService would only be set once, and the PackagingService would always work with the same instance of EmailService.
The traditional way to handle this is to create a factory interface for getting an email service, and populate that as a dependency into the PackagingService instance.
With the 'getter' based dependency injection, the container can modify the abstract 'getEmailService' or 'createEmailService' method to automatically return a new non-singleton/protype instance on each invocation.
Somebody else mentioned the difficulty of unit testing beans with abstract getters. While it is a bit more work, it is manageable by using a subclass in the unit test which actually implements the method.
Regards,
Colin -
Abstract classes? No problem![ Go to top ]
- Posted by: Howard Lewis Ship
- Posted on: May 27 2004 18:22 EDT
- in response to Colin Sampaleanu
This has been a big complaint in Tapestry ... abstract classes are just harder to test.
I just blogged about a utility class I've created for use in unit tests that instantiates abstract classes by creating a subclass on the fly. -
Getter-based Dependency Injection[ Go to top ]
- Posted by: Michal Maczka
- Posted on: May 28 2004 07:56 EDT
- in response to Colin Sampaleanu
This is useful mechanism in some cases. Something similar is coming to Spring fairly soon, probably a couple of weeks or so. Rod wrote some code a while ago, but it's waiting for somebody to polish it up a bit.http://article.gmane.org/gmane.comp.java.springframework.devel/4260/match=prototype+handling+supportWhat hasn't been mentioned in either Bob's blog entry or this TSS thread (unless I missed it), is that this is a very nice way to handle the situation where a singleton bean coming out of a container, needs to have dependencies populated in it which are themselves not singletons in terms of usage. So if I have a singleton 'PackagingService' coming out of a container, but it needs to work with a non-singleton (also called prototype) service as one of its dependencies, for example an 'EmailService', normal setter dependency injection has issues, because even if the EmailService bean was declared as a prototype in the container, the emailService property on the singleton PackagingService would only be set once, and the PackagingService would always work with the same instance of EmailService.The traditional way to handle this is to create a factory interface for getting an email service, and populate that as a dependency into the PackagingService instance.With the 'getter' based dependency injection, the container can modify the abstract 'getEmailService' or 'createEmailService' method to automatically return a new non-singleton/protype instance on each invocation.
with any type of dependecy injection this is possible. Any serious container
will not inject directly component istances but component connectors. In your example connector can contain ThredLocal instance of EmailService or some context dependend instance (e.g which was selected based on your security permission or some other more complex criteria).Somebody else mentioned the difficulty of unit testing beans with abstract getters. While it is a bit more work, it is manageable by using a subclass in the unit test which actually implements the method.Regards,Colin
Definitly!
But I don't think that such difficulty at all exists. Simply people who complain about it haven't yet seen how easly some containers can be used inside test case code.
The statement "classes which need container to run are difficult to test"
is completly false.
Getter-based Dependecy Injection is completly valid and components which
are written accordingly to this contract still can be very easly tested.
I just don't think that it is any better then field-based dependecy injection as this type of dependecy injection is not requiring any abtract methods or classes.
also:
public abstract Kissable getKissable();
can be change to
private abstract Kissable getKissable();
so component implementation is not required to "export" any methods which are the part of component internals.
In fact setter based dependecy injection whcih uses public methods has the same "feature". If this is a problem or not it depenends on interpretation.
Some OOP purists might say that this breakes encasulation and is a bad thing.
Michal -
Getter-based Dependency Injection[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 07:52 EDT
- in response to Dion Almaer
With the new code generation libraries like Javassist and CGLIB something like this is butt-simple to implement. FYI, Bob's example does not require abstract methods. You can implement the getter if you so desire, the container is just going to extend and reimplement the getter.
I think this is an interesting approach, but what I like about using AOP over something like this is that there is NO REQUIREMENT for a container. Intercepting a constructor or a field access with AOP allows you to plug in any mechanism you wanted to resolve a dependency(factory, JMX MBean Server, JNDI, CosNaming, LDAP, etc...). Also, this container approach gives you no mechanism to inject context/thread based dependencies, i.e. a security context, where an aspect hooked onto field access could.
Bill -
Getter-based Dependency Injection[ Go to top ]
- Posted by: Michal Maczka
- Posted on: May 28 2004 08:05 EDT
- in response to Bill Burke
Also, this container approach gives you no mechanism to inject context/thread based dependencies, i.e. a security context, where an aspect hooked onto field access could.Bill
Did you ever heard about connectors?! I thought that jboss makes extenisve use of dynamic proxies and this is what you are already been doing! :)
Michal -
Getter-based Dependency Injection[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 10:00 EDT
- in response to Michal Maczka
Duh! Sorry, my bad. Thanks for pointing it out...Also, this container approach gives you no mechanism to inject context/thread based dependencies, i.e. a security context, where an aspect hooked onto field access could.Bill
Did you ever heard about connectors?! I thought that jboss makes extenisve use of dynamic proxies and this is what you are already been doing! :)Michal -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Emmanuel Pirsch
- Posted on: May 28 2004 09:48 EDT
- in response to Dion Almaer
I believe that getter based DI superflous when using AOP to inject dependencies. Dependencies are implementation specifics. IMHO, They do not belong in the public interface of a class.
Field (private) based DI are much better. It's easily done using AOP and it does not pollute the public interface of an object with implementation details.
Documentation of the injection can be done (and proper pointcut definitions) by using annotation like it was discussed in this thread.
Emmanuel. -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Michal Maczka
- Posted on: May 28 2004 10:43 EDT
- in response to Emmanuel Pirsch
I believe that getter based DI superflous when using AOP to inject dependencies. Dependencies are implementation specifics. IMHO, They do not belong in the public interface of a class.
I agree that field based DI is at least as good as getter based DI.
Field (private) based DI are much better. It's easily done using AOP and it does not pollute the public interface of an object with implementation details.Documentation of the injection can be done (and proper pointcut definitions) by using annotation like it was discussed in this thread.Emmanuel.
But why to use AOP for that?
The code which phisically assignes dependecies to private fields
in pure Java takes no more then 50 lines of code and probably can be even much shorter. And it is something super simple. Code for AOP based solution will be approx. as long. I really feel that often people are searching for possibilties of using AOP just becouse
... they want to use AOP and are not even thinking how traditional techniques
can serve in such situtations. Sometimes they are as good or even better.
And this is imo such case.
Michal -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 11:40 EDT
- in response to Michal Maczka
I really feel that often people are searching for possibilties of using AOP just becouse ... they want to use AOP and are not even thinking how traditional techniques can serve in such situtations. Sometimes they are as good or even better. And this is imo such case.Michal
I don't think that is the case here.
AOP just gives you more possibilities and frees you from being dependent on a container to inject your dependencies. That is why it is an interesting approach.
I actually do not see any AOP going on in Bob's approach. Just a cool way of using dynamic class creation to implemet the getters. -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Michal Maczka
- Posted on: May 28 2004 14:45 EDT
- in response to Bill Burke
Sorry but you lost me.I really feel that often people are searching for possibilties of using AOP just becouse ... they want to use AOP and are not even thinking how traditional techniques can serve in such situtations. Sometimes they are as good or even better. And this is imo such case.Michal
I don't think that is the case here. AOP just gives you more possibilities and frees you from being dependent on a container to inject your dependencies. That is why it is an interesting approach.I actually do not see any AOP going on in Bob's approach. Just a cool way of using dynamic class creation to implemet the getters.
How possibly you can use the class
abstract Foo
{
abstract getBaa();
...
}
without the container?
and where do you want to use AOP then if not in container?
How conatiner will inject dependecies is competly not importand for
componet devlopers and componet deployers.
EJB 2.x are not that far from that model and implementations of spec are quite
different.
IMO this type of dependecy injection which is disussed in this thread is really quite extream in its requirement for container and such classes/components cannot exist witout the container.
I do belive that such approch is comptetly valid as I am big fan of containers I am using them pratically everytime and I am really against the way of thinking which assumes that classes should be usable inside and oustide containers. If somebody wants to write classes which are not dependent on a container he is free to do this but in reality it takes from him a lot of power and simplicity which is major profit of component oriented development.
Michal -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 28 2004 11:05 EDT
- in response to Emmanuel Pirsch
I believe that getter based DI superflous when using AOP to inject dependencies. Dependencies are implementation specifics. IMHO, They do not belong in the public interface of a class. Field (private) based DI are much better. It's easily done using AOP and it does not pollute the public interface of an object with implementation details.
The getters may be protected or even package-private. Intercepting field access is a little too much magic for me. -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 11:49 EDT
- in response to Bob Lee
Dynamically creating a class that implements all these getter methods is just as "magical", if not more so if you measure the amount of bytecode generated. Intercepting field access is all part of a fully-featured AOP implementation.I believe that getter based DI superflous when using AOP to inject dependencies. Dependencies are implementation specifics. IMHO, They do not belong in the public interface of a class. Field (private) based DI are much better. It's easily done using AOP and it does not pollute the public interface of an object with implementation details.
The getters may be protected or even package-private. Intercepting field access is a little too much magic for me. -
Getter^H^H^H^H^H^HField-based Dependency Injection[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 28 2004 12:11 EDT
- in response to Bill Burke
Dynamically creating a class that implements all these getter methods is just as "magical", if not more so if you measure the amount of bytecode generated. Intercepting field access is all part of a fully-featured AOP implementation.
No, it's not. With an abstract method, it's clear that someone will extend my class and provide an implementation. Whether that subclass is manually coded or dynamically generated is irrelevant. I don't usually expect some external actor to interfere with my accessing a private field. -
GetterField-based Dependency Injection[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 13:50 EDT
- in response to Bob Lee
If you want to make it clear with AOP that it may be injected, use an annotation to make it clearer:Dynamically creating a class that implements all these getter methods is just as "magical", if not more so if you measure the amount of bytecode generated. Intercepting field access is all part of a fully-featured AOP implementation.
No, it's not. With an abstract method, it's clear that someone will extend my class and provide an implementation. Whether that subclass is manually coded or dynamically generated is irrelevant. I don't usually expect some external actor to interfere with my accessing a private field.
@Injected Kissable myField;
or
/**
* For JDK 1.4 users
*
* @Injected
*/
Kissable myField;
pointcut: get(Kissable *->@Injected)
you could do the same with constructor or setter access as well. It is the same kind of hint that your abstract gives you, but a bit more clear to the developer( well, I should rather say, more clear to the maintainer of the code).
On Performance:
I think you need to rerun your numbers as JBoss AOP, AspectWerkz, and AspectJ have all gone through multiple releases since the benchmarks you posted on your initial release of dynaop.AspectJ, JBossAOP, and AspectWerkz, all kick the crap out of dynamic proxy based solutions as far as performance goes.
The implementation performs just fine. Micro benchmarks are irrelevant. Besides, last I checked dynaop (which uses dynamic proxies) outperformed JBossAOP, and unlike the three tools you mention, dynaop runs perfectly in any environment without custom tools or hooks.
Also, I don't knock the Dynamic Proxy approach. It is a good approach, but not always a complete one and not always as transparent to the user as you would like.
Bill -
GetterField-based Dependency Injection[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 28 2004 14:56 EDT
- in response to Bill Burke
@Injected Kissable myField;
I agree, that is more expressive. -
how to cache?[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 10:03 EDT
- in response to Dion Almaer
With this approach, don't you have to do additional bytecode enhancements to the subclass to avoid delegating to the container for every get? Even with the concurrent package, having the container as a shared resource ain't such a hot idea.
Bill -
how to cache?[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 28 2004 11:02 EDT
- in response to Bill Burke
With this approach, don't you have to do additional bytecode enhancements to the subclass to avoid delegating to the container for every get? Even with the concurrent package, having the container as a shared resource ain't such a hot idea.Bill
It uses a per-instance interceptor which keeps a reference to the component after the first invocation. -
how to cache?[ Go to top ]
- Posted by: Bill Burke
- Posted on: May 28 2004 11:43 EDT
- in response to Bob Lee
If you're using an interceptor, I don't see how you can claim better performance than a AOP based solution. AspectJ, JBossAOP, and AspectWerkz, all kick the crap out of dynamic proxy based solutions as far as performance goes.With this approach, don't you have to do additional bytecode enhancements to the subclass to avoid delegating to the container for every get? Even with the concurrent package, having the container as a shared resource ain't such a hot idea.Bill
It uses a per-instance interceptor which keeps a reference to the component after the first invocation. -
how to cache?[ Go to top ]
- Posted by: Bob Lee
- Posted on: May 28 2004 12:29 EDT
- in response to Bill Burke
AspectJ, JBossAOP, and AspectWerkz, all kick the crap out of dynamic proxy based solutions as far as performance goes.
The implementation performs just fine. Micro benchmarks are irrelevant. Besides, last I checked dynaop (which uses dynamic proxies) outperformed JBossAOP, and unlike the three tools you mention, dynaop runs perfectly in any environment without custom tools or hooks.