Intercepting method for execution time using Aspect [duplicate] - spring-boot

Please explain, why self invocation on proxy performed on target but not proxy? If that made on purpose, then why? If proxies created by subclassing, it's possible to have some code executed before each method call, even on self invocation. I tried, and I have proxy on self invocation
public class DummyPrinter {
public void print1() {
System.out.println("print1");
}
public void print2() {
System.out.println("print2");
}
public void printBoth() {
print1();
print2();
}
}
public class PrinterProxy extends DummyPrinter {
#Override
public void print1() {
System.out.println("Before print1");
super.print1();
}
#Override
public void print2() {
System.out.println("Before print2");
super.print2();
}
#Override
public void printBoth() {
System.out.println("Before print both");
super.printBoth();
}
}
public class Main {
public static void main(String[] args) {
DummyPrinter p = new PrinterProxy();
p.printBoth();
}
}
Output:
Before print both
Before print1
print1
Before print2
print2
Here each method called on proxy. Why in documentation mentioned that AspectJ should be used in case of self invocation?

Please read this chapter in the Spring manual, then you will understand. Even the term "self-invocation" is used there. If you still do not understand, feel free to ask follow-up questions, as long as they are in context.
Update: Okay, now after we have established that you really read that chapter and after re-reading your question and analysing your code I see that the question is actually quite profound (I even upvoted it) and worth answering in more detail.
Your (false) assumption about how it works
Your misunderstanding is about how dynamic proxies work because they do not work as in your sample code. Let me add the object ID (hash code) to the log output for illustration to your own code:
package de.scrum_master.app;
public class DummyPrinter {
public void print1() {
System.out.println(this + " print1");
}
public void print2() {
System.out.println(this + " print2");
}
public void printBoth() {
print1();
print2();
}
}
package de.scrum_master.app;
public class PseudoPrinterProxy extends DummyPrinter {
#Override
public void print1() {
System.out.println(this + " Before print1");
super.print1();
}
#Override
public void print2() {
System.out.println(this + " Before print2");
super.print2();
}
#Override
public void printBoth() {
System.out.println(this + " Before print both");
super.printBoth();
}
public static void main(String[] args) {
new PseudoPrinterProxy().printBoth();
}
}
Console log:
de.scrum_master.app.PseudoPrinterProxy#59f95c5d Before print both
de.scrum_master.app.PseudoPrinterProxy#59f95c5d Before print1
de.scrum_master.app.PseudoPrinterProxy#59f95c5d print1
de.scrum_master.app.PseudoPrinterProxy#59f95c5d Before print2
de.scrum_master.app.PseudoPrinterProxy#59f95c5d print2
See? There is always the same object ID, which is no surprise. Self-invocation for your "proxy" (which is not really a proxy but a statically compiled subclass) works due to polymorphism. This is taken care of by the Java compiler.
How it really works
Now please remember we are talking about dynamic proxies here, i.e. subclasses and objects created during runtime:
JDK proxies work for classes implementing interfaces, which means that classes implementing those interfaces are being created during runtime. In this case there is no superclass anyway, which also explains why it only works for public methods: interfaces only have public methods.
CGLIB proxies also work for classes not implementing any interfaces and thus also work for protected and package-scoped methods (not private ones though because you cannot override those, thus the term private).
The crucial point, though, is that in both of the above cases the original object already (and still) exists when the proxies are created, thus there is no such thing as polymorphism. The situation is that we have a dynamically created proxy object delegating to the original object, i.e. we have two objects: a proxy and a delegate.
I want to illustrate it like this:
package de.scrum_master.app;
public class DelegatingPrinterProxy extends DummyPrinter {
DummyPrinter delegate;
public DelegatingPrinterProxy(DummyPrinter delegate) {
this.delegate = delegate;
}
#Override
public void print1() {
System.out.println(this + " Before print1");
delegate.print1();
}
#Override
public void print2() {
System.out.println(this + " Before print2");
delegate.print2();
}
#Override
public void printBoth() {
System.out.println(this + " Before print both");
delegate.printBoth();
}
public static void main(String[] args) {
new DelegatingPrinterProxy(new DummyPrinter()).printBoth();
}
}
See the difference? Consequently the console log changes to:
de.scrum_master.app.DelegatingPrinterProxy#59f95c5d Before print both
de.scrum_master.app.DummyPrinter#5c8da962 print1
de.scrum_master.app.DummyPrinter#5c8da962 print2
This is the behaviour you see with Spring AOP or other parts of Spring using dynamic proxies or even non-Spring applications using JDK or CGLIB proxies in general.
Is this a feature or a limitation? I as an AspectJ (not Spring AOP) user think it is a limitation. Maybe someone else might think it is a feature because due to the way proxy usage is implemented in Spring you can in principle (un-)register aspect advices or interceptors dynamically during runtime, i.e. you have one proxy per original object (delegate), but for each proxy there is a dynamic list of interceptors called before and/or after calling the delegate's original method. This can be a nice thing in very dynamic environments. I have no idea how often you might want to use that. But in AspectJ you also have the if() pointcut designator with which you can determine during runtime whether to apply certain advices (AOP language for interceptors) or not.
Solutions
What you can do in order to solve the problem is:
Switch to native AspectJ, using load-time weaving as described in the Spring manual. Alternatively, you can also use compile-time weaving, e.g. via AspectJ Maven plugin.
If you want to stick with Spring AOP, you need to make your bean proxy-aware, i.e. indirectly also AOP-aware, which is less than ideal from a design point of view. I do not recommend it, but it is easy enough to implement: Simply self-inject a reference to the component, e.g. #Autowired MyComponent INSTANCE and then always call methods using that bean instance: INSTANCE.internalMethod(). This way, all calls will go through proxies and Spring AOP aspects get triggered.

#Dolphin
It is late reply but maybe this text will help you: Spring AOP and self-invocation.
In short, the link leads you to a simple example of why running code from another class will work but from "self" it won't.
Notice looking at the example from the link that when you run code from another class you are asking Spring to inject the bean. And Spring sees that in the bean you are asking for a cache, it creates at runtime proxy for that bean.
On the other hand, when you do the same in the "self" class, you create a compile time method call and Spring won't do anything about it.

Related

Autowiring interface vs class

If there are more than one implementation of an interface, then I would have to use #Qualifier to indicate which class I want to autowire with. Wouldn't it make more sense to autowire the class directly instead of interface?
This is what object oriented programming (especially abstraction and polymorphism) is about.
You build the classes independendent of concrete implementations and use an interface.
This allows you to change what implementation you use at any point.
Assume you have this:
public interface I{
void doSomething();
}
#Component("a")
public class A implements I{
public void doSomething(){
//...
}
public void doSomethingElse(){
//...
}
}
#Component("b")
public class B implements I{
public void doSomething(){
//...
}
}
If you use
#Autowired
private A yourVariable;
you might be tempted to use the doSomethingElse() method that is an implementation detail (by what reason whatsoever).
However, if you use
#Qualifier("a")
private I yourVariable;
this cannot happen as the method is not present in the interface.
This gives you the ability to swap the implementation at any time.
Wouldn't it make more sense to autowire the class directly instead of interface?
This pretty much depends on how exactly do you work with qualifiers but in general, the answer is "No", autowiring the class is a bad thing to do if you have an interface - you should always work by interface.
Here are the examples:
interface I { void foo(); }
class IImpl1 implements I {
void foo() {System.out.println("Impl1");
pubic void bar() {// another method - why not?}
}
class IImpl2 implements I { void foo() {System.out.println("Impl2"); }
Note, that an implementation IImpl1 has an additional method bar that doesn't belong to the interface I
Case 1:
#Component
public class Driver {
#Autowired
private IImpl1 i;
}
Here class Driver is tightly could to the concrete implementation IImpl1 in general I can call method bar from the Driver class because I have this implementation, but in this case if I'll have to switch the implementation of Driver in future you'll have to also change the code: both change the reference, and also get rid of calls to IImpl1.bar() that might be not that easy to do - its a change in logic. As a result, the whole polymorphic behavior is lost.
By far its the worst way to program.
Now, consider Case 2:
#Component
public class Driver {
#Autowired
#Qualifier("someLogicalName") // under the hood it spring will map it to IImpl1 but you don't know that here
I i;
}
In this case - the things are much better - you never couple the driver to the concrete implementation at the level of code. This means that in general its enough to change the qualifier to get another implementation. You can't call bar anymore - it won't compile.
You also do not know what the implementation will be injected. If in future the implementation of the component that actually implements the logic of "someLogicalName" will change (by that I mean that you'll create a new class IImpl3), you won't feel it here - you'll place that qualifier on that new class and all the places that use it will get that implementation automatically.
Case 3:
#Configuration
public class MyConfiguration {
#Bean
public Driver driver(#Qualifier("someLogicalName") I i) {
return new Driver(i);
}
}
public class Driver {
private final I i;
public Driver(I i) { // in real life this constructor can be generated by
// lombok or something, put it here for the sake of completeness
this.i = i;
}
}
This by far the most "clean" approach - conceptually its really similar to case 2, however in this case you don't place the qualifier at the level of Driver class at all, in fact, the class Driver is not even aware at the level of code / metadata that its related to Spring anyhow. Of course all the "advantages" of case 2 are also applicable here as well.

Why does self-invocation not work for Spring proxies (e.g. with AOP)?

Please explain, why self invocation on proxy performed on target but not proxy? If that made on purpose, then why? If proxies created by subclassing, it's possible to have some code executed before each method call, even on self invocation. I tried, and I have proxy on self invocation
public class DummyPrinter {
public void print1() {
System.out.println("print1");
}
public void print2() {
System.out.println("print2");
}
public void printBoth() {
print1();
print2();
}
}
public class PrinterProxy extends DummyPrinter {
#Override
public void print1() {
System.out.println("Before print1");
super.print1();
}
#Override
public void print2() {
System.out.println("Before print2");
super.print2();
}
#Override
public void printBoth() {
System.out.println("Before print both");
super.printBoth();
}
}
public class Main {
public static void main(String[] args) {
DummyPrinter p = new PrinterProxy();
p.printBoth();
}
}
Output:
Before print both
Before print1
print1
Before print2
print2
Here each method called on proxy. Why in documentation mentioned that AspectJ should be used in case of self invocation?
Please read this chapter in the Spring manual, then you will understand. Even the term "self-invocation" is used there. If you still do not understand, feel free to ask follow-up questions, as long as they are in context.
Update: Okay, now after we have established that you really read that chapter and after re-reading your question and analysing your code I see that the question is actually quite profound (I even upvoted it) and worth answering in more detail.
Your (false) assumption about how it works
Your misunderstanding is about how dynamic proxies work because they do not work as in your sample code. Let me add the object ID (hash code) to the log output for illustration to your own code:
package de.scrum_master.app;
public class DummyPrinter {
public void print1() {
System.out.println(this + " print1");
}
public void print2() {
System.out.println(this + " print2");
}
public void printBoth() {
print1();
print2();
}
}
package de.scrum_master.app;
public class PseudoPrinterProxy extends DummyPrinter {
#Override
public void print1() {
System.out.println(this + " Before print1");
super.print1();
}
#Override
public void print2() {
System.out.println(this + " Before print2");
super.print2();
}
#Override
public void printBoth() {
System.out.println(this + " Before print both");
super.printBoth();
}
public static void main(String[] args) {
new PseudoPrinterProxy().printBoth();
}
}
Console log:
de.scrum_master.app.PseudoPrinterProxy#59f95c5d Before print both
de.scrum_master.app.PseudoPrinterProxy#59f95c5d Before print1
de.scrum_master.app.PseudoPrinterProxy#59f95c5d print1
de.scrum_master.app.PseudoPrinterProxy#59f95c5d Before print2
de.scrum_master.app.PseudoPrinterProxy#59f95c5d print2
See? There is always the same object ID, which is no surprise. Self-invocation for your "proxy" (which is not really a proxy but a statically compiled subclass) works due to polymorphism. This is taken care of by the Java compiler.
How it really works
Now please remember we are talking about dynamic proxies here, i.e. subclasses and objects created during runtime:
JDK proxies work for classes implementing interfaces, which means that classes implementing those interfaces are being created during runtime. In this case there is no superclass anyway, which also explains why it only works for public methods: interfaces only have public methods.
CGLIB proxies also work for classes not implementing any interfaces and thus also work for protected and package-scoped methods (not private ones though because you cannot override those, thus the term private).
The crucial point, though, is that in both of the above cases the original object already (and still) exists when the proxies are created, thus there is no such thing as polymorphism. The situation is that we have a dynamically created proxy object delegating to the original object, i.e. we have two objects: a proxy and a delegate.
I want to illustrate it like this:
package de.scrum_master.app;
public class DelegatingPrinterProxy extends DummyPrinter {
DummyPrinter delegate;
public DelegatingPrinterProxy(DummyPrinter delegate) {
this.delegate = delegate;
}
#Override
public void print1() {
System.out.println(this + " Before print1");
delegate.print1();
}
#Override
public void print2() {
System.out.println(this + " Before print2");
delegate.print2();
}
#Override
public void printBoth() {
System.out.println(this + " Before print both");
delegate.printBoth();
}
public static void main(String[] args) {
new DelegatingPrinterProxy(new DummyPrinter()).printBoth();
}
}
See the difference? Consequently the console log changes to:
de.scrum_master.app.DelegatingPrinterProxy#59f95c5d Before print both
de.scrum_master.app.DummyPrinter#5c8da962 print1
de.scrum_master.app.DummyPrinter#5c8da962 print2
This is the behaviour you see with Spring AOP or other parts of Spring using dynamic proxies or even non-Spring applications using JDK or CGLIB proxies in general.
Is this a feature or a limitation? I as an AspectJ (not Spring AOP) user think it is a limitation. Maybe someone else might think it is a feature because due to the way proxy usage is implemented in Spring you can in principle (un-)register aspect advices or interceptors dynamically during runtime, i.e. you have one proxy per original object (delegate), but for each proxy there is a dynamic list of interceptors called before and/or after calling the delegate's original method. This can be a nice thing in very dynamic environments. I have no idea how often you might want to use that. But in AspectJ you also have the if() pointcut designator with which you can determine during runtime whether to apply certain advices (AOP language for interceptors) or not.
Solutions
What you can do in order to solve the problem is:
Switch to native AspectJ, using load-time weaving as described in the Spring manual. Alternatively, you can also use compile-time weaving, e.g. via AspectJ Maven plugin.
If you want to stick with Spring AOP, you need to make your bean proxy-aware, i.e. indirectly also AOP-aware, which is less than ideal from a design point of view. I do not recommend it, but it is easy enough to implement: Simply self-inject a reference to the component, e.g. #Autowired MyComponent INSTANCE and then always call methods using that bean instance: INSTANCE.internalMethod(). This way, all calls will go through proxies and Spring AOP aspects get triggered.
#Dolphin
It is late reply but maybe this text will help you: Spring AOP and self-invocation.
In short, the link leads you to a simple example of why running code from another class will work but from "self" it won't.
Notice looking at the example from the link that when you run code from another class you are asking Spring to inject the bean. And Spring sees that in the bean you are asking for a cache, it creates at runtime proxy for that bean.
On the other hand, when you do the same in the "self" class, you create a compile time method call and Spring won't do anything about it.

static vs default method - Functional interfaces

I am creating functional interfaces and want to reuse default methods with anonymous implementation.
public class JavaInterfaceTest {
public static void main(String[] args) {
FunctionalIntf fi = () -> {
System.out.println("In ananymus impl, trying to call default method");
// doInternal()
return "Hello";
};
fi.doFunction(); // How this line valid ?
fi.doInternal();
FunctionalIntf.doSomething();
}
}
#FunctionalInterface
interface FunctionalIntf {
String doFunction();
default void doInternal(){
System.out.println("In doInternal");
}
static void doSomething(){
System.out.println("In doSomething");
}
}
How fi.doFunction(); is valid, if I go thru anonymous implementation.
How can I re-sue default method or static method if I want from implementation?
3. Is returning something valid/best practice in my case as I can not handle the returned value.
When you are creating the anonymous class, you actually provide an implementation for your abstract method doFunction() from FunctionalIntf interface. So when you are using this line of code:
fi.doFunction();
It means that you are calling doFunction() method from the anonymous class. This is another example on how functional interfaces work:
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println("I'm Runnable!");
}
};
r.run();
In this case we override run() method from Runnable interface, which is also a functional interface.
You cannot provide another implementation for the static method because you cannot override a static method. Static methods are not inherited in Java at all. You can instead provide another implementation for the default method by overriding as mentioned in my above example.
Regarding the returned value, you need to define your method to return the exact value you need. There is no best practice in that.
When you implement a functional interface, you have 2 options:
Use lambdas, as you have
Use inner classes.
If you use lambdas, like you have, you have the default implementation of the static/default methods along with the implementation of the abstract method.
If you use an inner class, the normal rules of overriding applies.

Spring AOP does not run as expected [duplicate]

I have several Aspects coded in my application. All others works except for the following.
Service Interface
package com.enbiso.proj.estudo.system.service;
...
public interface MessageService {
...
Message reply(Message message);
Message send(Message message);
...
}
Service Implementation
package com.enbiso.proj.estudo.system.service.impl;
....
#Service("messageService")
public class MessageServiceImpl implements MessageService {
...
#Override
public Message reply(Message message) {
...
return this.send(message);
}
#Override
public Message send(Message message) {
...
}
}
Aspect
#Aspect
#Component
public class NewMessageAspect {
...
#AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(..))",
returning = "message")
public void perform(Message message){
...
}
}
When I try to execute the send method the debug point is not getting hit in the aspect perform.
UPDATE
I did some investigations and found that this doesn't work, when the send method is invoked from the reply method as below
#Autowire MessageService messageService;
...
messageService.reply(message);
But if I call the method messageService.send(message) it works fine. But as reply method is calling send method internally, shouldn't it also invoke the aspect?
I have no idea what i have done wrong. Please help me.
Thank you jst for clearing the things up. Just for the information purposes for the future developer in SO, I'm posting the full answer to this question
Lets assume that there is a bean from SimplePojo
public class SimplePojo implements Pojo {
public void foo() {
this.bar();
}
public void bar() {
...
}
}
When we call the method foo(), it reinvokes the method bar() inside it. Even thought the method foo() is invoked from the AOP Proxy, the internal invocation of the bar() is not covered by the AOP Proxy.
So eventually this makes, if there are any advices attached to the method bar() to not get invoked
Solution
Use AopContext.currentProxy() to call the method. Unfortunately this couples the logic with AOP.
public void foo() {
((Pojo) AopContext.currentProxy()).bar();
}
Reference:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies
You are running into a limitation of Spring AOP on self-invocation. You basically can get around it by using AopContext.currentProxy(), refactor code into different beans, or use full ApsectJ weaving.
See explanation here and workaround(s).
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies
I guess the problem is the #args condition.
Spring documentation states the following:
#args - limits matching to join points (the execution of methods when using Spring AOP) where the runtime type of the actual arguments passed have annotations of the given type(s)
Therefore the parameter of #args has to be a type expression. So the correct pointcut expression is
#AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(..)) && args(com.enbiso.proj.estudo.system.service.impl.Message")
or simply
#AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(com.enbiso.proj.estudo.system.service.impl.Message))")
Please adjust the package of Message if it doesn't fit.

Practical Usage of HttpSessionBindingListener And HttpSessionAttributeListener

I am reading through head first JSP and servlets. Going through different type of listeners, I came across HttpSessionBindingListener and HttpSessionAttributeListener.
I was thinking about the difference between the two - I want to see the practical usages in real world examples of those two listeners. I tested HttpSessionBindingListener by implementing valueBound() and valueUnBound() - why would an object need to know whether it has been added or not?
I am pretty confused about the practical usages. Please help in clarifying this.
The HttpSessionBindingListener is to be implemented on the class whose instances may be stored in the session, such as the logged-in user.
E.g.
public class ActiveUser implements HttpSessionBindingListener {
#Override
public void valueBound(HttpSessionBindingEvent event) {
logins.add(this);
}
#Override
public void valueUnbound(HttpSessionBindingEvent event) {
logins.remove(this);
}
}
When an instance of this ActiveUser get set as a session attribute by HttpSession#setAttribute(), then the valueBound() will be invoked. When it get removed by either HttpSession#removeAttribute(), or an invalidate of the session, or get replaced by another HttpSession#setAttribute(), then the valueUnbound() will be invoked.
Here are some real world use cases:
Getting SessionScoped bean from HttpSessionListener?
How to call a method before the session object is destroyed?
Call an action when closing a JSP
implementing HttpSessionListener
How to access HTTP sessions in Java
The HttpSessionAttributeListener is to be implemented as an application wide #WebListener which get invoked when any attribute is added, removed or replaced in the HttpSession. Continuing with the above ActiveUser example, this is particularly useful if you can't modify the ActiveUser class to implement HttpSessionBindingListener (because it's 3rd party or so), or when you want to make use of a "marker interface" on an arbitrary amount of classes so that you can do the listening job in a single central place.
#WebListener
public class ActiveUserListener implements HttpSessionAttributeListener {
#Override
public void attributeAdded(HttpSessionBindingEvent event) {
if (event.getValue() instanceof ActiveUser) {
logins.add(event.getValue());
}
}
#Override
public void attributeRemoved(HttpSessionBindingEvent event) {
if (event.getValue() instanceof ActiveUser) {
logins.remove(event.getValue());
}
}
#Override
public void attributeReplaced(HttpSessionBindingEvent event) {
if (event.getValue() instanceof ActiveUser) {
logins.add(event.getValue());
}
}
}
Here's a real world use case:
Getting notification when bounded/unbounded to a HTTP session

Resources