I have added #Profiled annotation for public and private method. I can see the timing logs for public methods. But there is no timing logs for private methods.
I did the configurations correctly.
#Profiled
public BigInteger nextPrime() {
currentPrime = currentPrime.nextProbablePrime();
return currentPrime;
}
#Profiled
private void test()
{
try{
Thread.sleep(100);
}catch(Exception e)
{
e.printStackTrace();
}
}
Is #profiled annotation only applicable for only public methods?
Most likely you have configured perf4j with Spring AOP and since Spring AOP proxies are not invoked when a method is called from inside the same class (as in your case with the test method), no performance statistics will be recorded.
Check out this blog post which explains Spring AOP pitfalls
One solution to your problem would be to use AspectJ with perf4j, since AspectJ can handle this type of situation
Yes. It is limitation of the Spring AOP:
When using proxies, you should apply the you annotations only to
methods with public visibility. If you do annotate protected, private
or package-visible methods with these annotations, no error is raised,
but the annotated method does not exhibit the configured caching
settings. Consider the use of AspectJ (see below) if you need to
annotate non-public methods as it changes the bytecode itself.”
Related
I have recently noticed that Spring successfully intercepts intra class function calls in a #Configuration class but not in a regular bean.
A call like this
#Repository
public class CustomerDAO {
#Transactional(value=TxType.REQUIRED)
public void saveCustomer() {
// some DB stuff here...
saveCustomer2();
}
#Transactional(value=TxType.REQUIRES_NEW)
public void saveCustomer2() {
// more DB stuff here
}
}
fails to start a new transaction because while the code of saveCustomer() executes in the CustomerDAO proxy, the code of saveCustomer2() gets executed in the unwrapped CustomerDAO class, as I can see by looking at 'this' in the debugger, and so Spring has no chance to intercept the call to saveCustomer2.
However, in the following example, when transactionManager() calls createDataSource() it is correctly intercepted and calls createDataSource() of the proxy, not of the unwrapped class, as evidenced by looking at 'this' in the debugger.
#Configuration
public class PersistenceJPAConfig {
#Bean
public DriverManagerDataSource createDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
//dataSource.set ... DB stuff here
return dataSource;
}
#Bean
public PlatformTransactionManager transactionManager( ){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(createDataSource());
return transactionManager;
}
}
So my question is, why can Spring correctly intercept the intra class function calls in the second example, but not in the first. Is it using different types of dynamic proxies?
Edit:
From the answers here and other sources I now understand the following:
#Transactional is implemented using Spring AOP, where the proxy pattern is carried out by wrapping/composition of the user class. The AOP proxy is generic enough so that many Aspects can be chained together, and may be a CGLib proxy or a Java Dynamic Proxy.
In the #Configuration class, Spring also uses CGLib to create an enhanced class which inherits from the user #Configuration class, and overrides the user's #Bean functions with ones that do some extra work before calling the user's/super function such as check if this is the first invocation of the function or not. Is this class a proxy? It depends on the definition. You may say that it is a proxy which uses inheritance from the real object instead of wrapping it using composition.
To sum up, from the answers given here I understand these are two entirely different mechanisms. Why these design choices were made is another, open question.
Is it using different types of dynamic proxies?
Almost exactly
Let's figure out what's the difference between #Configuration classes and AOP proxies answering the following questions:
Why self-invoked #Transactional method has no transactional semantics even though Spring is capable of intercepting self-invoked methods?
How #Configuration and AOP are related?
Why self-invoked #Transactional method has no transactional semantics?
Short answer:
This is how AOP made.
Long answer:
Declarative transaction management relies on AOP (for the majority of Spring applications on Spring AOP)
The Spring Framework’s declarative transaction management is made possible with Spring aspect-oriented programming (AOP)
It is proxy-based (§5.8.1. Understanding AOP Proxies)
Spring AOP is proxy-based.
From the same paragraph SimplePojo.java:
public class SimplePojo implements Pojo {
public void foo() {
// this next method invocation is a direct call on the 'this' reference
this.bar();
}
public void bar() {
// some logic...
}
}
And a snippet proxying it:
public class Main {
public static void main(String[] args) {
ProxyFactory factory = new ProxyFactory(new SimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(new RetryAdvice());
Pojo pojo = (Pojo) factory.getProxy();
// this is a method call on the proxy!
pojo.foo();
}
}
The key thing to understand here is that the client code inside the main(..) method of the Main class has a reference to the proxy.
This means that method calls on that object reference are calls on the proxy.
As a result, the proxy can delegate to all of the interceptors (advice) that are relevant to that particular method call.
However, once the call has finally reached the target object (the SimplePojo, reference in this case), any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy.
This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute.
(Key parts are emphasized.)
You may think that aop works as follows:
Imagine we have a Foo class which we want to proxy:
Foo.java:
public class Foo {
public int getInt() {
return 42;
}
}
There is nothing special. Just getInt method returning 42
An interceptor:
Interceptor.java:
public interface Interceptor {
Object invoke(InterceptingFoo interceptingFoo);
}
LogInterceptor.java (for demonstration):
public class LogInterceptor implements Interceptor {
#Override
public Object invoke(InterceptingFoo interceptingFoo) {
System.out.println("log. before");
try {
return interceptingFoo.getInt();
} finally {
System.out.println("log. after");
}
}
}
InvokeTargetInterceptor.java:
public class InvokeTargetInterceptor implements Interceptor {
#Override
public Object invoke(InterceptingFoo interceptingFoo) {
try {
System.out.println("Invoking target");
Object targetRetVal = interceptingFoo.method.invoke(interceptingFoo.target);
System.out.println("Target returned " + targetRetVal);
return targetRetVal;
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
System.out.println("Invoked target");
}
}
}
Finally InterceptingFoo.java:
public class InterceptingFoo extends Foo {
public Foo target;
public List<Interceptor> interceptors = new ArrayList<>();
public int index = 0;
public Method method;
#Override
public int getInt() {
try {
Interceptor interceptor = interceptors.get(index++);
return (Integer) interceptor.invoke(this);
} finally {
index--;
}
}
}
Wiring everything together:
public static void main(String[] args) throws Throwable {
Foo target = new Foo();
InterceptingFoo interceptingFoo = new InterceptingFoo();
interceptingFoo.method = Foo.class.getDeclaredMethod("getInt");
interceptingFoo.target = target;
interceptingFoo.interceptors.add(new LogInterceptor());
interceptingFoo.interceptors.add(new InvokeTargetInterceptor());
interceptingFoo.getInt();
interceptingFoo.getInt();
}
Will print:
log. before
Invoking target
Target returned 42
Invoked target
log. after
log. before
Invoking target
Target returned 42
Invoked target
log. after
Now let's take a look at ReflectiveMethodInvocation.
Here is a part of its proceed method:
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
++this.currentInterceptorIndex should look familiar now
Here is the target
And there are interceptors
the method
the index
You may try introducing several aspects into your application and see the stack growing at the proceed method when advised method is invoked
Finally everything ends up at MethodProxy.
From its invoke method javadoc:
Invoke the original method, on a different object of the same type.
And as I mentioned previously documentation:
once the call has finally reached the target object any method calls that it may make on itself are going to be invoked against the this reference, and not the proxy
I hope now, more or less, it's clear why.
How #Configuration and AOP are related?
The answer is they are not related.
So Spring here is free to do whatever it wants. Here it is not tied to the proxy AOP semantics.
It enhances such classes using ConfigurationClassEnhancer.
Take a look at:
CALLBACKS
BeanMethodInterceptor
BeanFactoryAwareMethodInterceptor
Returning to the question
If Spring can successfully intercept intra class function calls in a #Configuration class, why does it not support it in a regular bean?
I hope from technical point of view it is clear why.
Now my thoughts from non-technical side:
I think it is not done because Spring AOP is here long enough...
Since Spring Framework 5 the Spring WebFlux framework has been introduced.
Currently Spring Team is working hard towards enhancing reactive programming model
See some notable recent blog posts:
Reactive Transactions with Spring
Spring Data R2DBC 1.0 M2 and Spring Boot starter released
Going Reactive with Spring, Coroutines and Kotlin Flow
More and more features towards less-proxying approach of building Spring applications are introduced. (see this commit for example)
So I think that even though it might be possible to do what you've described it is far from Spring Team's #1 priority for now
Because AOP proxies and #Configuration class serve a different purpose, and are implemented in a significantly different ways (even though both involve using proxies).
Basically, AOP uses composition while #Configuration uses inheritance.
AOP proxies
The way these work is basically that they create proxies that do the relevant advice logic before/after delegating the call to the original (proxied) object. The container registers this proxy instead of the proxied object itself, so all dependencies are set to this proxy and all calls from one bean to another go through this proxy. However, the proxied object itself has no pointer to the proxy (it doesn't know it's proxied, only the proxy has a pointer to the target object). So any calls within that object to other methods don't go through the proxy.
(I'm only adding this here for contrast with #Configuration, since you seem to have correct understanding of this part.)
#Configuration
Now while the objects that you usually apply the AOP proxy to are a standard part of your application, the #Configuration class is different - for one, you probably never intend to create any instances of that class directly yourself. This class truly is just a way to write configuration of the bean container, has no meaning outside Spring and you know that it will be used by Spring in a special way and that it has some special semantics outside of just plain Java code - e.g. that #Bean-annotated methods actually define Spring beans.
Because of this, Spring can do much more radical things to this class without worrying that it will break something in your code (remember, you know that you only provide this class for Spring, and you aren't going to ever create or use its instance directly).
What it actually does is it creates a proxy that's subclass of the #Configuration class. This way, it can intercept invocation of every (non-final non-private) method of the #Configuration class, even within the same object (because the methods are effectively all overriden by the proxy, and Java has all the methods virtual). The proxy does exactly this to redirect any method calls that it recognizes to be (semantically) references to Spring beans to the actual bean instances instead of invoking the superclass method.
read a bit spring source code. I try to answer it.
the point is how spring deal with the #Configurationand #bean.
in the ConfigurationClassPostProcessor which is a BeanFactoryPostProcessor, it will enhance all ConfigurationClasses and creat a Enhancer as a subClass.
this Enhancer register two CALLBACKS(BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor).
you call PersistenceJPAConfig method will go through the CALLBACKS. in BeanMethodInterceptor,it will get bean from spring container.
it may be not clearly. you can see the source code in ConfigurationClassEnhancer.java BeanMethodInterceptor.ConfigurationClassPostProcessor.java enhanceConfigurationClasses
You can't call #Transactional method in same class
It's a limitation of Spring AOP (dynamic objects and cglib).
If you configure Spring to use AspectJ to handle the transactions, your code will work.
The simple and probably best alternative is to refactor your code. For example one class that handles users and one that process each user. Then default transaction handling with Spring AOP will work.
Also #Transactional should be on Service layer and not on #Repository
transactions belong on the Service layer. It's the one that knows about units of work and use cases. It's the right answer if you have several DAOs injected into a Service that need to work together in a single transaction.
So you need to rethink your transaction approach, so your methods can be reuse in a flow including several other DAO operations that are roll-able
Spring uses proxying for method invocation and when you use this... it bypasses that proxy. For #Bean annotations Spring uses reflection to find them.
I have a custom annotation:
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface FeatureSwitch {
String featureName();
}
I intercept this with the below aspect and use it to check if a feature is on or off. If the feature is off, then I throw an exception.
Aspect:
#Aspect
public class FeatureSwitchAspect {
private final FeatureSwitchConfigurationApi featureSwitchConfigurationApi;
public FeatureSwitchAspect(final FeatureSwitchConfigurationApi featureSwitchConfigurationApi) {
this.featureSwitchConfigurationApi = featureSwitchConfigurationApi;
}
#Before("#annotation(featureSwitch)")
public void checkFeatureSwitch(final FeatureSwitch featureSwitch) {
final String featureName = featureSwitch.featureName();
Boolean featSwitch = featureSwitchConfigurationApi.isFeatureActive(featureName);
if (!featSwitch) {
throw new FeatureSwitchOffException();
}
}
}
The problem I am having is that the behaviour seems inconsistent. This seems to do as expected when I call a method from a different class, but if I make a call to an annotated private method, no interception occurs. Have I got it configured incorrectly? Any suggestions would be appreciated.
Method calls from within classes will not work with proxy-based AOP.
Since you are using the keyword this (which is a pointer to your original object and not the proxy objects that is wrapping it), you will be calling the wrapped method directly - thus bypassing the code added as a result of your AOP.
You have tagged your question by java and aop, not by spring or spring-aop. So I assume that you are not limited to proxy-based Spring AOP but can use a full-fledged AOP solution like AspectJ (possible even within Spring or application servers). If so, there is a solution:
Use a privileged aspect. Caveat: This is supported in native AspectJ syntax, but not in #AspectJ syntax.
Main References for My Question:
Writing Method Interceptors for Google Guice: http://code.google.com/p/google-guice/wiki/AOP
The JavaDoc for the MethodInterceptor interface: http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html
General references about Java annotations: http://docs.oracle.com/javase/tutorial/java/javaOO/annotations.html and http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html
Now My Question:
I am writing a Java application that heavily relies on Google Guice for creating objects and handling dependency injection. I am trying to use interceptors to run pre-processing code before certain annotated methods are executed. So far, I have successfully been able to execute interceptors (using the MethodInterceptor interface) on methods that have been annotated, using Guice's instructions. However, I want to now write interceptors that will execure on Parameter Annotations.
Here is an example scenario. First, I create my own annotation. For example::
#BindingAnnotation
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PARAMETER)
public #interface MyParameterAnnotation {
}
Next, I write my own interceptor for this annotation:
public class MyParameterAnnotationInterceptor implements MethodInterceptor {
#Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// Do some stuff
return invocation.proceed();
}
}
Here's an example of how I intend on using #MyParameterAnnotation:
public class ExampleObject {
public String foo(#MyParameterAnnotation String param) {
...
}
}
Finally, I need to create a Guice Injector and use it to create an instalce of ExampleObject, or else I cannot use a method interceptor in this project. I configure the Injector so that the MyParameterAnnotationInterceptor is bound to #MyParameterAnnotation, like so:
final MethodInterceptor interceptor = new MyParameterAnnotationInterceptor();
requestStaticInjection(MyParameterAnnotationInterceptor.class);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(MyParameterAnnotation.class), interceptor);
When I follow the above steps and execute a call to ExampleObject.foo(), unfortunately the interceptor is not executed despite the parameter being marked by #MyParameterAnnotation. Note that these similar steps will work if the annotation was placed at the method level instead.
This leads me to come up with two possible conclusions: either Guice cannot support binding an interceptor to a parameter annotation, or I am doing something completely incorrect (perhaps I should use another AOP Alliance interface for the interceptor, like FieldInterceptor, but I highly doubt it because the JavaDoc for Guice's AbstractModule suggests that the bindInterceptor() method can only use a MethodInterceptor parameter).
Nonetheless, all help us much appreciated :)
The matcher is for method annotations not method parameter annotations.
There is no matcher provided by Guice for method parameter annotations--you either have to write one yourself or use some other scheme. Note that this is a bit of an odd use case--Generally you can get away with
public class ExampleObject {
#MyAnnotation
public String foo(String param) {
...
}
}
You have the right Guice interceptor config for the above example.
If I have a #Transactional -annotation on a private method in a Spring bean, does the annotation have any effect?
If the #Transactional annotation is on a public method, it works and open a transaction.
public class Bean {
public void doStuff() {
doPrivateStuff();
}
#Transactional
private void doPrivateStuff() {
}
}
...
Bean bean = (Bean)appContext.getBean("bean");
bean.doStuff();
The answer your question is no - #Transactional will have no effect if used to annotate private methods. The proxy generator will ignore them.
This is documented in Spring Manual chapter 10.5.6:
Method visibility and #Transactional
When using proxies, you should apply
the #Transactional annotation only
to methods with public visibility. If
you do annotate protected, private or
package-visible methods with the
#Transactional annotation, no error
is raised, but the annotated method
does not exhibit the configured
transactional settings. Consider the
use of AspectJ (see below) if you need
to annotate non-public methods.
The Question is not private or public, the question is: How is it invoked and which AOP implementation you use!
If you use (default) Spring Proxy AOP, then all AOP functionality provided by Spring (like #Transactional) will only be taken into account if the call goes through the proxy. -- This is normally the case if the annotated method is invoked from another bean.
This has two implications:
Because private methods must not be invoked from another bean (the exception is reflection), their #Transactional Annotation is not taken into account.
If the method is public, but it is invoked from the same bean, it will not be taken into account either (this statement is only correct if (default) Spring Proxy AOP is used).
#See Spring Reference: Chapter 9.6 9.6 Proxying mechanisms
IMHO you should use the aspectJ mode, instead of the Spring Proxies, that will overcome the problem. And the AspectJ Transactional Aspects are woven even into private methods (checked for Spring 3.0).
By default the #Transactional attribute works only when calling an annotated method on a reference obtained from applicationContext.
public class Bean {
public void doStuff() {
doTransactionStuff();
}
#Transactional
public void doTransactionStuff() {
}
}
This will open a transaction:
Bean bean = (Bean)appContext.getBean("bean");
bean.doTransactionStuff();
This will not:
Bean bean = (Bean)appContext.getBean("bean");
bean.doStuff();
Spring Reference: Using #Transactional
Note: In proxy mode (which is the default), only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with #Transactional!
Consider the use of AspectJ mode (see below) if you expect self-invocations to be wrapped with transactions as well. In this case, there won't be a proxy in the first place; instead, the target class will be 'weaved' (i.e. its byte code will be modified) in order to turn #Transactional into runtime behavior on any kind of method.
If you need to wrap a private method inside a transaction and don't want to use AspectJ, you can use TransactionTemplate.
#Service
public class MyService {
#Autowired
private TransactionTemplate transactionTemplate;
private void process() {
transactionTemplate.executeWithoutResult(status -> processInTransaction());
}
private void processInTransaction(){
//...
}
}
Yes, it is possible to use #Transactional on private methods, but as others have mentioned this won't work out of the box. You need to use AspectJ. It took me some time to figure out how to get it working. I will share my results.
I chose to use compile-time weaving instead of load-time weaving because I think it's an overall better option. Also, I'm using Java 8 so you may need to adjust some parameters.
First, add the dependency for aspectjrt.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.8</version>
</dependency>
Then add the AspectJ plugin to do the actual bytecode weaving in Maven (this may not be a minimal example).
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Finally add this to your config class
#EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
Now you should be able to use #Transactional on private methods.
One caveat to this approach: You will need to configure your IDE to be aware of AspectJ otherwise if you run the app via Eclipse for example it may not work. Make sure you test against a direct Maven build as a sanity check.
Spring Docs explain that
In proxy mode (which is the default), only external method calls
coming in through the proxy are intercepted. This means that
self-invocation, in effect, a method within the target object calling
another method of the target object, will not lead to an actual
transaction at runtime even if the invoked method is marked with
#Transactional.
Consider the use of AspectJ mode (see mode attribute in table below)
if you expect self-invocations to be wrapped with transactions as
well. In this case, there will not be a proxy in the first place;
instead, the target class will be weaved (that is, its byte code will
be modified) in order to turn #Transactional into runtime behavior on
any kind of method.
Another way is user BeanSelfAware
The answer is no. Please see Spring Reference: Using #Transactional
:
The #Transactional annotation may be placed before an interface definition, a method on an interface, a class definition, or a public method on a class
Same way as #loonis suggested to use TransactionTemplate one may use this helper component (Kotlin):
#Component
class TransactionalUtils {
/**
* Execute any [block] of code (even private methods)
* as if it was effectively [Transactional]
*/
#Transactional
fun <R> executeAsTransactional(block: () -> R): R {
return block()
}
}
Usage:
#Service
class SomeService(private val transactionalUtils: TransactionalUtils) {
fun foo() {
transactionalUtils.executeAsTransactional { transactionalFoo() }
}
private fun transactionalFoo() {
println("This method is executed within transaction")
}
}
Don't know whether TransactionTemplate reuse existing transaction or not but this code definitely do.
I'm currently using slf4j on top of log4j for logging. I would like to automagically log any use of a deprecated method (annotated with the standard #Deprecated annotation) in my code.
Is there any easy way to do this ?
If you want to log every use you will probably have to use AOP. It depends on what Frameworks you are using if there is an easy way to do this. This is how it might look like in Spring:
public class DeprecatedLoggerAdvice implements MethodInterceptor
{
private Logger log = LoggerFactory.getLogger(this.getClass());
#Override
public Object invoke(MethodInvocation invocation) throws Throwable
{
Methode method = invocation.getMethod();
Annotation[] annotations = method.getAnnotations();
boolean isDeprecated = // Check it annotations has the deprecated one in here
if(isDeprecated)
{
log.warn("Called deprecated method {}", method.getName());
}
invocation.proceed();
}
}
Though as already mentioned this is not good on performance. If you are using it in your application you should use that approach in combination with unit tests that cover most of your code. Then you can log and remove the use of deprecated methods and then disable AOP in production mode.
I can't think of an easy way to do it, but you could use the annotation processing tool to generate code that logs the use of each deprecated method.
I think you would be sorry if you did this at runtime. Sure you could use Aspect4J to put an AOP pointcut on every method that looks for annotations; but the performance cost would be high.
You can but it is going to be tough. The only solution AFAIK to "detect" method calls is by using AOP. In your case, you can write an aspect which inspects every single method call and checks if it is deprecated and logs them.
If you use spring you can start http://static.springsource.org/spring/docs/2.5.x/reference/aop.html
Please be advised that AOP has performance implications and should be used only after giving careful consideration. Perhaps you can have a flag that enables this feature in a dev/qa environment and disables them in PROD