Spring proxy: BeanPostProcessor or AOP? - java

We can create proxy for the target bean in the postProcessAfterInitialization() method of BeanPostProcessor.
Or we can use AOP - and proxy will also be created through Dynamic Proxy or CGlib.
What is the difference?
When should we use BPP and when AOP?

As far as I know bean-post-processor is a more powerful tool. It can complete replace the bean (so you can even shoot in your own foot). On the other hand AOP approach has very handy pattern matching solution. In a bean-post-processor approach you get an Object and you have to recognize what is its type. Moreover AOP approach is more about adding a behaviour related to pattern-selected methods' execution. With bean-post-processor you can replace (or just modify) a whole bean which possibly affects all of its method.

Related

Why in Spring AOP the object are wrapped into a JDK proxy that implements interfaces?

I am studying Spring and I have the followig
Consider the following bean definition:
<bean id="clientService" class="com.myapp.service.ClientServiceImpl" />
Now consider the case on which it is declared a pointcut* targetting all methods inside the **clientService bean.
Consider also that the ClientServiceImpl class implements 3 interfaces
Now I know that using AOP the clientService bean is proxied and that this proxy implements all the 3 interfaces.
But what is the exact reason for which all these 3 interface are implemented?
So it seems to me that exist 2 kinds of proxies (correct me if I am saying wrong assertions):
JDK Proxy: used by default from Spring (is it true?) in wicht I have an interface that define the method of the object that I want to proxify. So the concrete implementation of this interface is wrapped by the proxy. So when I call a method on my object I am calling it on its proxy. The call is recognized by a method interceptor that eventually perform the aspect and then is performed the invoked method.
CGLIB Proxy: in wich, it seems to me that, the proxy extend the implementation of the wrapped object adding to it the extra logic features
Something like this:
So it seems to me that Spring use the first kind of proxy that is based on the implementation of interfaces (is it right?):
I think that in AOP the extra logic is represented by the implementation of the method interceptor (is it true?) and the standard logic is represented by the implementation of the method defined into the interfaces.
But, if the previous reasoning are correct, my doubts is: why I need to define these interface and do that the object wrapped by the object implement these interfaces? (I can't understand if the proxy itself implement these interfaces).
Why? How exactly works?
Tnx
But what is the exact reason for which all these 3 interface are
implemented?
If the proxy didn't implement all of those interfaces, the bean couldn't be wired into other beans that use that interface (you'd get a ClassCastException). For example, autowiring all of the beans of that interface into a bean. Additionally, things like getBeanNamesForType wouldn't work if the proxy didn't implement the interface.
So it seems to me that exist 2 kinds of proxies (correct me if I am
saying wrong assertions)
Yes that's correct. See ScopedProxyMode. By default, Spring won't create a proxy. It only creates a proxy if it needs to wrap the bean to add additional behavior (AOP). Note that there's also a special case of the CGLIB based proxy that uses Objenesis to deal with subclassing targets that don't have a default constructor.
CGLIB Proxy: in wich, it seems to me that, the proxy extend the
implementation of the wrapped object adding to it the extra logic
features
When you use CGLIB based proxies, the constructor for your bean gets called twice: once when the dynamically generated subclass is instantiated (to create the proxy) and a second time when the actual bean is created (the target).
I think that in AOP the extra logic is represented by the
implementation of the method interceptor (is it true?)
The proxy is essentially just invoking the chain of advice needs to be applied. That advice isn't implemented in the proxy itself. For example, the advice for #Transactional lives in TransactionAspectSupport. Take a look at the source to JdkDynamicAopProxy.
and the standard logic is represented by the implementation of the
method defined into the interfaces.
Assuming that you're programming against interfaces and using JDK proxies that's correct.
But, if the previous reasoning are correct, my doubts is: why I need
to define these interface and do that the object wrapped by the object
implement these interfaces? (I can't understand if the proxy itself
implement these interfaces).
If you want to use interface based proxies you need to use interfaces. Just make sure all of your beans implement interfaces, all of your advised methods are defined by those interfaces, and that when one bean depends on another bean, that dependency is specified using an interface. Spring will take care of constructing the proxy and making sure it implements all of the interfaces.
In your diagram, you have "Spring AOP Proxy (this)". You have to be really careful with using this when you're using any type of proxying.
Calls within the same class won't have advice applied because those calls won't pass through the proxy.
If in one of your beans you pass this to some outside code, you're passing the target of the AOP advice. If some other code uses that reference, the calls won't have AOP advice applied (again, you're bypassing the proxy).

Caching internal bean calls

I have the similar problem as described in this thread: http://forum.spring.io/forum/attic/spring-modules/22590-can-t-cache-result-of-inner-method-call
But I don't like to decompose my bean in a chain just for caching. In my case I need to create a chain of three fake beans just for caching!
I understand that the caching proxy just delegates all calls to the original bean, so inner calls cannot be intercepted. I understand this in case of java config -- I've just created my bean with the 'new' keyword. But why I got the same behavior on xml config? I expect that Spring can extend my class with its constructors and create an instance of a new class. So all inner calls will be also go through the caching layer due to polymorphism.
Is there any way to force inheritance but not delegation to the original bean?
Thanks,
Alexey
I've just found the chapter in the reference. It says that "Spring AOP is proxy-based." There is a way to access reference to a real proxy: AopContext.currentProxy()) to call it instead of "this" bean.

Get application components without #Autowired

How would you extract something prior 2.5 version from .xml config? It bothers me because if #Autowired is removed from my arsenal I would not really know what to do.
Say I want to use some DAO implementation.
In service class I usually write:
#Autowired
someDaoInterface generalDao;
Then I typically call
generalDao.someInterfaceMethod(someParam param);
How would I extract implementation from config in Spring 2.0 to use this method?
Is it as dumb as just: new ApplicationContext(pathToXml) and then use .getBean or there is other way?
Why do I ask for taking bean out from configuration file?
Because in Spring MVC how can you perform your logic without getting beans out from the application context.
If you have #Controller handler then you need to make calls to the service classes' methods? So they should be somehow retrieved from the context and the only way so far is using #Autowired? Then I would also want to populate Service classes as I stated in previous example with DAO classes and they also need to be retrieved from the application context, so I would be able to write logic for service classes themself. How would people do it in the past?
I see the #Autowired as the only mean of taking something out, not because it is convenient to wire automatically - I am perfectly ok with XML.
You still have option to wire it explicitely via property or constructor parameter. (Anyway, autowired is not going to work if there is ambiguity in your container )
Of course, you can use application context and getBean() in your java code, but it violates DI pattern and makes all the spring stuff useless. Purpose of DI is to decouple your business loginc from implementation details - it's not business logic it's how and where it dependencies come from. Dependencies are just there.
By using ApplicationContext.getBean() you are breaking this pattern, and introduce dependency to:
spring itself
your configuration names
After you done this, you can as well drop use of DI and spring because you just voided all the advandages DI is providing to you. (BTW, #Autowired also introduces dependency to spring, and violates DI pattern, it also implies that there is only one instance available)
Also, answer is: in ideal case there shall be no reference to spring in your code at all.
No imports, no annotations - just interfaces of collaborating entities.

How to specify interceptor at inject time

I have some beans for which, in specific injections, I want to add a given interceptor.
I was naïvely thinking there was something like a #Interceptors annotation that could allow me to write
private #Interceptors(Logging.class, Connection.class) #Inject MyBean instance;
Unfortunatly, Weld documentation clearly states the opposite.
So, how could I inject an intercepted version of my bean ? Is it possible using a cdi Instance object ?
EDIT
Although LightGuard's answser is really relevant, it doesn't totally answser my question, so let me rephrase it.
I want to have an annotation that triggers some kind of method call event sending. For that, I created a CDI Interceptor, complete with its own interceptor binding (let's say interceptor is called SenderInterceptor, and the binding is called SenderBinding). What I want now is to add a CDI qualifier (let's call it SenderQualifier) that, when used for an injection, installs SenderInterceptor.
To be more clear, I want the following code to use SenderInterceptor
/* calling any method of that bean should trigger an event */
private #Inject #SenderQualifier MyBean aBean;
while this one doesn't
private #Inject MyBean aBean;
What I tried so far was
detecting fields requiring those injections using reflections library (that works)
create using seam solder an AnnotatedType from bean class (during the BeforeBeanDiscovery event) (the type is created, but not really distinguishable from the initial one) and giving that AnnotatedType the interceptor binding annotation.
create using seam solder (again) a Bean from generated AnnotatedType, and giving it the required qualifier annotation
All seems to worrk, except it's the original bean which gets injected.
I could of course replace original one with intercepted one, but there are some cases where such interception is not required, so I have to keep both AnnotatedType refering the same concrete type. I was thinking I coulld do that in CDI, but it doesn't seems to work (as original type is never replaced by intercepted one).
What you would need to do:
Add the interceptor to beans.xml so it's activated
Create an extension to add the interceptor binding or the interceptor annotation to the type in ProcessAnnotatedType life cycle event. You'll need to call getAnnotatedType, add the annotation(s) then call setAnnotatedType. I strongly recommend looking at Seam Solder or Apache DeltaSpike project for the AnnotatedTypeBuilder to make this easier.
Possibly, you could try #Inject MyInterceptedBean instance;, where the interceptors are listed with the MyInterceptedBean?
(Caveat: this does not look right, though, using inheritance for types that only differ in annotations ... probably acceptable when it's always the two stated same annotations and not different annotations in each case.)

Annotated Spring #Controller also as Bean?

Can an annotated Spring MVC Controller also be annotated with #Component/#Service type of annotations and be used both as a controller and as a bean?
Edit: placing more emphasis on the software design aspect, and updating the API link to SpringV3
As mentioned in other answers, this is not an ideal approach to Spring MVC, but nevertheless the controller will already be available for autowiring in your ApplicationContext.
It's already a Bean in your ApplicationContext, so you can auto-wire it by type. There's no need to add an #Component annotation.
From the Spring API Docs: "This annotation serves as a specialization of #Component, allowing for implementation classes to be autodetected through classpath scanning."
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Controller.html
The same holds true for #Service.
Although I've done it myself, I would not normally recommend this design approach.
If possible, refactor the required functionality into a separate bean, which can then be (auto-)wired into both the #Controller, and any other bean, as required.
If, as you have commented, you are 'cornered' into this decision (as I was, by previous design choices), then so be it.
HTH
It can but it shouldn't. A web controller should be an entry point, nothing else.
Any reusable logic it performs should be in a dedicated service layer, not in the controller itself
No, sounds like it's doing too much. One or the other, not both. I don't know if it's possible (I doubt it), but I'm sure it's not advisable.
I think that you should hear more about patterns like Front Controller, MVC, DAO and Multitier architecture and so on.

Categories

Resources