Baeldung has this section:
this limits matching to join points where the bean reference is an
instance of the given type, while target limits matching to join
points where the target object is an instance of the given type. The
former works when Spring AOP creates a CGLIB-based proxy, and the
latter is used when a JDK-based proxy is created. Suppose that the
target class implements an interface:
public class FooDao implements BarDao {
...
}
In this case, Spring AOP will use the JDK-based proxy, and we should
use the target PCD because the proxied object will be an instance of
the Proxy class and implement the BarDao interface:
#Pointcut("target(com.baeldung.pointcutadvice.dao.BarDao)")
On the other hand, if FooDao doesn't implement any interface, or the
proxyTargetClass property is set to true, then the proxied object will
be a subclass of FooDao and we can use the this PCD:
#Pointcut("this(com.baeldung.pointcutadvice.dao.FooDao)")
I'm still confuse why this just works with CGLIB proxy and target just works with JDK proxy. Could you help to tell me the different between them?
Actually, the explanation in the tutorial does not make much sense:
Both this(MyInterface) and target(MyInterface) work for JDK proxies, if the bean is declared as a MyInterface type.
Both this(MyClass) and target(MyClass) work for CGLIB proxies, if the bean is declared as a MyClass type.
Just try, and you will see that I am right. In Spring AOP, there is not real difference between this() and target(), because due to its proxy-based nature, it implicitly only supports execution() pointcuts from AspectJ.
In native AspectJ however, you also have other pointcut types such as call(), and there you would see a difference: this() would match the caller's type, while target() would match the callee's type. E.g., if you intercept a method A.a() calling B.b() via pointcut call(B.b()), this() would return an A instance, while target() would return a B instance. Do not worry, if this is difficult to understand for you, because for Spring AOP and execution pointcuts it really does not matter.
The only subtle difference I noticed in Spring AOP is, that for MyInterfaceImpl implements MyInterface, pointcut target(MyInterfaceImpl) would actually match, while this(MyInterfaceImpl) would not. This is because for JDK proxies, the proxy actually extends java.lang.reflect.Proxy, not MyInterfaceImpl. The proxy only delegates to a MyInterfaceImpl instance.
Edit: If you keep in mind that, in contrast to native AspectJ which involves no dynamic proxies, the semantics in Spring AOP are such that
this() relates to the proxy object, while
target() relates to the proxied object (proxy target),
it becomes clear why in this special case for JDK proxies target() matches, but this() does not.
Reference: Spring manual, section "Declaring a pointcut - examples":
this(com.xyz.service.AccountService): Any join point (method execution only in Spring AOP) where the proxy implements the AccountService interface.
target(com.xyz.service.AccountService): Any join point (method execution only in Spring AOP) where the target object implements the AccountService interface.
Only in this case, we are not asking for the interface class (which both the proxy and the target object implement), but for the implementation class itself.
Bottom line: For all intents and purposes, in normal use cases you can use either this() or target() for both JDK and CGLIB proxies. I recommend to stick with target(), because it best matches the implicit execution() semantics of Spring AOP, and usually you are interested in information about the target rather than about the proxy..
Related
I read about guice AOP in the documentation here :- https://github.com/google/guice/wiki/AOP
From the documentation :-
Behind the scenes, method interception is implemented by generating bytecode at runtime. Guice dynamically creates a subclass that applies interceptors by overriding methods. If you are on a platform that doesn't support bytecode generation (such as Android), you should use Guice without AOP support.
What does the documentation means by extending the subclass. Is this the method interceptor subclass? Does it work by using reflection to intercept the method? The reason I ask this question is because in the documentation, this line is followed by this :-
Due to this, we have the following limitations on the guice AOP
a) AOP cannot be applied to a private method.
Unclear to me why AOP cannot be applied to a private method.
Unclear to me why AOP cannot be applied to a private method.
Because private methods are not inherited by subclasses, i.e. there is no way to intercept a private method and then delegate to it because the subclass cannot even call that method. This is a normal Java limitation and has nothing to do with AOP specifically.
BTW, if you want a full-fledged, powerful AOP tool working with any JVM language and able to intercept private methods without the need to resort to dynamic proxies (subclasses created during runtime like Guice or Spring AOP), just use AspectJ.
What does the documentation means by extending the subclass.
The JRE knows the concept of dynamic proxies in order to be able to intercept method calls and (optionally) delegate to the original call before/after doing something else in an interceptor method. This works for interfaces only, but CGLIB extends this concept to subclasses of non-interface classes, which is why in proxy-based AOP frameworks such as Spring AOP (and maybe Guice, not 100% sure) proxies are used in order to implement AOP. AspectJ works differently, it does not use or need any dynamic proxies or other types of subclasses.
I have a class A, a cache A_CACHE and a proxy object AProxy extends A. My goal is to serialize AProxy objects as if they are A objects (automatically substitute type) and put them into A_CACHE.
Is there any way in Apache Ignite to substitute type of an object that I am trying to put into cache (serialize using BinarySerializer)?
What I have tried so far.
I have implemented and registered the same BinarySerializer for both types. I have also tried to play with BinaryNameMapper class to return the same class name for both classes, but without success. The only option that comes to my mind now is to use BinaryObjectBuilder. Is it really the only option for me?
After a small research the solution was found.
AProxy should implement writeReplace method of Serializable interface. Return proxied instance from this method. If proxied class is Serializable or Externalizable and one wants to apply custom serialization, than Binarylizable interface should be implemented by proxied class (custom binary serializers are not applied when using the hack above, but instead OptimizedMarshaller is being used).
I read this on a guideline
"When using Spring AOP always use interfaces so normal AOP proxying can be used (rather than CGLIB)"
What could than mean? I have very good idea on AOP and have implemented AOP myself before. But completely out of clue.
Simply said there are 2 way for proxying an object :
dynamic : you create a new object that implement the same interface than the target object and encapsulate this last in addition with the proxy logic
static : when you compile the target class you add the aspect logic directly into the compiled class (cglib way)
Dynamic proxy can only apply on object that implement an interface and will be used only if you reference the instance using the interface (which is advised here) whereas static proxy can apply on everything
Following the spring guideline will allow you to use any of the method (you can simply switch using spring configuation) instead of being coupled to cglib.
Note than static proxy allow proxy logic to be applied even when you call a proxied method from another method inside the same class whereas with dynamic proxy the call must come from outside.
I am trying to convert a Guice inject project to a Java EE project, that is to run on glassfish.
I have a lib project, that defines an interface, Hello, annotated with #Remote. Then I have an impl project that has a bean, HelloBean, annotated with #Stateless, and a single constructor with parameters and #Inject.
Then I have a was project that depends on the lib and it's interface to create a webservice, HelloService, annotated with #WebService, and Hello as a member annotated with #EJB.
This does not seem to work. Since beans must have a no-args constructor, I created HelloBean as a bean, and HelloImpl as a Pojo with a single #Inject constructor, with arguments. I have tried then injecting Hello and HelloImpl into HelloBean with both #Inject, #Resource and #EJB. None seem to work.
If I #Inject Hello or HelloImpl into HelloBean, I get a NPE.
If I #Resource Hello or HelloImpl, I get an Lookup failed for delegate.
If I #EJB HelloImpl, same error. #EJB Hello and I get stackoverflows (understandably).
I do want to use constructor injection, as I feel it's a more correct way of creating classes (they are always valid once constructed). But I don't see how it's possible to combine CDI and EJBs.
How can I get a Pojo with an #Inject constructor into a bean? Or is my plan fundamentally flawed?
A better way is to define a initialize method annotated with #Inject. Any parameters will be injection points and should be supplied via CDI. You can also do this with constructors. Make sure you have WEB-INF/beans.xml as well.
We are implementing IoC/DI in our application using NInject framework. We are having internal classes having internal methods. To implement IoC/DI, we have to extract interfaces. But if we are having only internal methods in an internal class, we can't extract interface for that class.
So is there a way to implement IoC/DI in such cases (internal class having only internal methods) or should we change our internal methods to public methods. Kindly suggest. Thanks
If your class is already internal then there is absolutely not difference between internal and public methods. public methods of internal classes are only internally visible.
If you stay with injecting concrete classes though you loose all the advantages of DI. So yes you should extract (internal) interfaces and inject the interfaces. This requires that the configuration code has access to the classes by either beeing in the same assembly of the assembly must be declased as friend assembly. Futhermore, you have to configure Ninject to allow none public classes. See NinjectSettings.
The only thing that you really need to make public is the interface (not the concrete implementation).
You can use an abstract factory or (easier) Ninject to map the public interface to the internal concrete; thus your client code just has to request an instance of "a thing" that implements the interface and your factory / container will return the implementation.
You should read up on Dependency Inversion Principle as well as it goes hand-in-hand with this.
You could use InternalsVisibleTo attribute in AssemblyInfo.cs file like this
[assembly: InternalsVisibleTo("Assembly_That_Should_Access_The_Internal_Class")]