I have a Spring Application where I have the following skeleton class
class ServiceCaller
{
public Result callService()
{
//call a remote service
}
}
Since calling a remote service is an expensive operation, I added caching in my application. I used EhCache Spring annotations #Cacheable and applied it to the callService() method. Everything was working fine and my Result objects were getting correctly cached.
Later I wanted to add a logger across all my ServiceCallers such that my logger would record every actual call to a remote service. I did not want to manually add logger.info() to every such callService method so I decided to use a Spring AOP to implement this.
I defined a pointcut after-returning to all the methods that I wanted to log. It was working; however I noticed that my logger point cut was invoked even when I had a cache hit and my actual callService method was not called. This, I observed, was happening because the order of my proxy to the ServiceCaller bean was as follows: AOPPointCutProxy(EhCacheCachingProxy(ServiceCallerBean)). I want my logger pointcut to be invoked only when my actual callService method is called and not when it is returning with a cached value from the EhCache proxy. Which means that I actually want my proxy creation hierarchy to be in the form of EhCacheCachingProxy(AOPPointCutProxy(ServiceCallerBean)). Note that my bean definitions, pointcut definitions, cache configs may all be in different randomly named xml files.
So how do I enforce Spring to create the proxies in the order I want?
That is what the Ordered interface is used for. You need to implement that on your beans.
You can create a proxy that gets all of the proxies injected that should surround you call. Only that composite proxy surrounds the actual bean. Upon invocation it calls the injected proxies in their specified order.
Related
I am new to Spring and read that we can't use #Cacheable with static method but can't found why we can't use so any one can explain so that beginner can understood easily?
Can we use static method for retrieving database table?
I have made static method of all method of service layer of DAO so Is this thread-safe?
Elaborating on my comment:
"Static methods cannot be cached. The way aspects work in Spring is by adding a wrapper class (a proxy) to the annotated class. There is no way in Java to add a wrapper to a static method."
Since Spring needs an object to wrap around in order to intercept calls to that object and perform various operations before delegating the modified input to the original object (thus spring aspects are possible).
Since anything that is static cannot be instantiated as an object, Spring has no way to wrap around it and intercept its calls (at least with the current implementation of Spring)
It is a limitation of the mechanism used to provide caching.
When you mark some method as #Cacheable, Spring creates a proxy to your bean that intercepts method invocations and provides the caching, and will inject that instead of the original bean. So if you have some code like:
#Inject
private MyBean myBean;
...
myBean.myMethod("foo");
where MyBean has declared myMethod() as #Cacheable, then myBean will not point to what you put in the application context, but to a proxy that will do the caching and invoke the original MyBean.myMethod() only when cache lookup does not return anything.
Proxys cannot intercept static methods, so the proxy cannot cache static methods. That is why #Cacheable will not work on static methods.
I'd like to know what the expected lifecycle behavior is for a class that responds to REST requests.
I have a class that's derived from javax.ws.rs.core.Application that identifies another class for responding to requests.
In that other class, it is annotated with #Path("foo") and methods within this class are annotated with #Path("bar"). When a request is made to foo/bar, I can see that the constructor is executed, then the PostConstruct method is properly called. After the method returns a response to the client, I can see that PreDestroy is called and then the class is squashed. On the next request, the process repeats.
Is this the correct behavior? Or is there a way that this class can remain in memory so that it doesn't need to go through the constructor and PostConstruct each time a request is made? This method relies on JAXB marshalling and various XSL transformations - I would like to cache the compiled XSLT transformation objects as well as the results of some transformations, but if the class is reinstantiated each time it is called, it makes it impossible for local caching.
This is running with Java 7, Wink, and Tomcat 7. Can someone please let me know if this is the expected behavior, or am I missing something that will just keep this class alive?
Thanks.
By JAX-RS specification, the Resources (the classes annotated with #Path) are created per request.
There are several ways to override this behavior.
The simplest way that can be used according to the JAX-RS specification, is to create a resource instance yourself (you are responsible to call the PostConstruct, not sure when and how you call to PostDestroy in this case) and return it using javax.ws.rs.core.Application.getSingletons()
Alternately, you can put #org.apache.wink.common.annotations.Scope(ScopeType.SINGLETON) annotation on your resource.
If you use Spring, Wink has a neat Spring integration module, so the Spring's lifecycle will be used. See http://incubator.apache.org/wink/1.0/html/5.5%20Spring%20Integration.html
I have sucessfully used Guice to Inject Providers into the servlet portion of an existing java web application, however, I can't access the injectors through the business layer (non-servlet java classes) of the application.
I have read up on Injecting the Injector, but to me that seems more like a hack and in several places, including the Guice documentation, it says not to do that too much.
I guess my question is, Where do I bootstrap a java web app so that the non-servlet/filter classes have access to the injector created in the class I use to extend GuiceServletContextListener? Is there any way to make those classes injectable without injecting the injector?
Thank you and let me know if you need any clarification.
Edit:
I am attempting to do this with a simple logger, so far, in my
servlets, I call:
#Inject
private static org.slf4j.Logger log;
The injection is set up in MyLoggerModule as follows (which is in the
createInjector call with ServletModule) :
#Override
public void configure() {
bindListener(Matchers.any(), new SLF4JTypeListener()); // I
built my own SLF4JTypeListener...
}
This all works perfectly in the servlets, but the field injection does
not work when called by a class that is not a servlet or filter.
Guice doesn't intercept calls for new objects, so if your business layer isn't already using Guice to create the objects that need injection, it'll need modification to do so.
The injection only works when handled by Guice during injection. So starting from the base injector you've made, whatever is marked with #Inject which is needed for the instance you've requested will be provided by Guice as best it can, and in turn, during instanciation of those, further #Inject annotations will be filled in by providers and bindings until nothing new needs to be instanciated. From that point on however you are not going to get fields injected into servlets created outside Guice's injection, perhaps by calling new somewhere, which is likely what your Object Factory is doing.
You'll need to change your Object Factory to use providers instead of new. If you could edit these, it wouldn't be too hard to do since Guice can give you default providers for bindings.
So one way your business layer could be Guice aware is to have whatever is creating servlets first create an Injector and then request the servlets be created by the injector. If this means you'll have more than one injector, then yes, that will be a problem but only for the objects you want to be singletons. So you could make a factory pattern class for a singleton injector, or you could find where these classes (here typed bar) which are creating servlets themselves are created (in foo), and then start with the injector there (in foo) using one Guice injector to create those (bar type) classes and also modifying them (bar type) to request a provider for the servlets which they'll use instead of making calls for a new servlet.
Now that I think about this, it could be simple if it kind of only happens once or twice for 10-20 servlet types, or it could be complicated if there's some framework that defines totally flexible behavior for what gets newed up when and why.
Another option would be avoiding #Inject on fields at all times, as recommended. So now your servlets are taking in an org.slf4j.Logger as a construction parameter. The constructor is marked #Inject, and it assigns the parameter's value to the field. Then any place you're not using injection should break with an incorrect number of parameters at a new call. Fix these by figuring out how to either get the servlet provided here instead, or how to get a provider for the servlet into the class.
Not sure what you mean... if you inject objects in to your servlets/filters, those objects have their dependencies injected by Guice as well, and so on all the way down.
How are you creating the classes that you're trying to inject this logger in to? They must be created by Guice to be injected, which means no new.
When using Spring AOP to create a proxy for a class using NameMatchMethodPointcutAdvisor and BeanNameAutoProxyCreator does this essentially proxy every call to the object, but only apply the advice to the matched methods, or somehow create a Proxied object that only has those methods and uses the normal object for the calls that are supposed to be intercepted?
The way, I think I understand it is that it does proxy every call to the object but then only calls the Advisor on the methods that match - but I can't find a good example/post to confirm this.
Depends on the technique used. (It is configurable by an attribute proxy-target-class in your aop config)
JDK dynamic proxies are proxies by interface - each methods of the interface goes through the proxy, as you said, and if it matches happens to be an "advised" method, the advisor is applied. Otherwise it is delegated to the original object
CGLIB proxies are effectively subclasses defined at runtime of your concrete classes. I can't be sure in this, but I assume only the "advised" methods are overridden, the rest retain the definition of the superclass.
However, no matter which mechanism is used:
it isn't your concern how exactly are the proxies implemented
this doesn't impact performance in a significant way - Debunking myths: proxies impact performance by the Spring team about proxy performance myths
or somehow create a Proxied object that only has those methods and uses the normal object for the calls that are supposed to be intercepted?
How would this actually work? When a class has a reference to the class that is being proxied, it only has one reference to it. It either has to invoke a proxy class or a non-proxied class. Spring can't know which methods you are calling and therefore can't give you one type if you need to call the advised method and another type if you're not.
I want to know what actually happens when you annotate a method with #Transactional?
Of course, I know that Spring will wrap that method in a Transaction.
But, I have the following doubts:
I heard that Spring creates a proxy class? Can someone explain this in more depth. What actually resides in that proxy class? What happens to the actual class? And how can I see Spring's created proxied class
I also read in Spring docs that:
Note: Since this mechanism is based on proxies, 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!
Source: http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
Why only external method calls will be under Transaction and not the self-invocation methods?
This is a big topic. The Spring reference doc devotes multiple chapters to it. I recommend reading the ones on Aspect-Oriented Programming and Transactions, as Spring's declarative transaction support uses AOP at its foundation.
But at a very high level, Spring creates proxies for classes that declare #Transactional on the class itself or on members. The proxy is mostly invisible at runtime. It provides a way for Spring to inject behaviors before, after, or around method calls into the object being proxied. Transaction management is just one example of the behaviors that can be hooked in. Security checks are another. And you can provide your own, too, for things like logging. So when you annotate a method with #Transactional, Spring dynamically creates a proxy that implements the same interface(s) as the class you're annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.
Transactions in EJB work similarly, by the way.
As you observed, through, the proxy mechanism only works when calls come in from some external object. When you make an internal call within the object, you're really making a call through the this reference, which bypasses the proxy. There are ways of working around that problem, however. I explain one approach in this forum post in which I use a BeanFactoryPostProcessor to inject an instance of the proxy into "self-referencing" classes at runtime. I save this reference to a member variable called me. Then if I need to make internal calls that require a change in the transaction status of the thread, I direct the call through the proxy (e.g. me.someMethod().) The forum post explains in more detail.
Note that the BeanFactoryPostProcessor code would be a little different now, as it was written back in the Spring 1.x timeframe. But hopefully it gives you an idea. I have an updated version that I could probably make available.
When Spring loads your bean definitions, and has been configured to look for #Transactional annotations, it will create these proxy objects around your actual bean. These proxy objects are instances of classes that are auto-generated at runtime. The default behaviour of these proxy objects when a method is invoked is just to invoke the same method on the "target" bean (i.e. your bean).
However, the proxies can also be supplied with interceptors, and when present these interceptors will be invoked by the proxy before it invokes your target bean's method. For target beans annotated with #Transactional, Spring will create a TransactionInterceptor, and pass it to the generated proxy object. So when you call the method from client code, you're calling the method on the proxy object, which first invokes the TransactionInterceptor (which begins a transaction), which in turn invokes the method on your target bean. When the invocation finishes, the TransactionInterceptor commits/rolls back the transaction. It's transparent to the client code.
As for the "external method" thing, if your bean invokes one of its own methods, then it will not be doing so via the proxy. Remember, Spring wraps your bean in the proxy, your bean has no knowledge of it. Only calls from "outside" your bean go through the proxy.
Does that help?
As a visual person, I like to weigh in with a sequence diagram of the proxy pattern. If you don't know how to read the arrows, I read the first one like this: Client executes Proxy.method().
The client calls a method on the target from his perspective, and is silently intercepted by the proxy
If a before aspect is defined, the proxy will execute it
Then, the actual method (target) is executed
After-returning and after-throwing are optional aspects that are
executed after the method returns and/or if the method throws an
exception
After that, the proxy executes the after aspect (if defined)
Finally the proxy returns to the calling client
(I was allowed to post the photo on condition that I mentioned its origins. Author: Noel Vaes, website: https://www.noelvaes.eu)
The simplest answer is:
On whichever method you declare #Transactional the boundary of transaction starts and boundary ends when method completes.
If you are using JPA call then all commits are with in this transaction boundary.
Lets say you are saving entity1, entity2 and entity3. Now while saving entity3 an exception occur, then as enitiy1 and entity2 comes in same transaction so entity1 and entity2 will be rollback with entity3.
Transaction :
entity1.save
entity2.save
entity3.save
Any exception will result in rollback of all JPA transactions with DB.Internally JPA transaction are used by Spring.
All existing answers are correct, but I feel cannot give this complex topic justice.
For a comprehensive, practical explanation you might want to have a look at this Spring #Transactional In-Depth guide, which tries its best to cover transaction management in ~4000 simple words, with a lot of code examples.
It may be late but I came across something which explains your concern related to proxy (only 'external' method calls coming in through the proxy will be intercepted) nicely.
For example, you have a class that looks like this
#Component("mySubordinate")
public class CoreBusinessSubordinate {
public void doSomethingBig() {
System.out.println("I did something small");
}
public void doSomethingSmall(int x){
System.out.println("I also do something small but with an int");
}
}
and you have an aspect, that looks like this:
#Component
#Aspect
public class CrossCuttingConcern {
#Before("execution(* com.intertech.CoreBusinessSubordinate.*(..))")
public void doCrossCutStuff(){
System.out.println("Doing the cross cutting concern now");
}
}
When you execute it like this:
#Service
public class CoreBusinessKickOff {
#Autowired
CoreBusinessSubordinate subordinate;
// getter/setters
public void kickOff() {
System.out.println("I do something big");
subordinate.doSomethingBig();
subordinate.doSomethingSmall(4);
}
}
Results of calling kickOff above given code above.
I do something big
Doing the cross cutting concern now
I did something small
Doing the cross cutting concern now
I also do something small but with an int
but when you change your code to
#Component("mySubordinate")
public class CoreBusinessSubordinate {
public void doSomethingBig() {
System.out.println("I did something small");
doSomethingSmall(4);
}
public void doSomethingSmall(int x){
System.out.println("I also do something small but with an int");
}
}
public void kickOff() {
System.out.println("I do something big");
subordinate.doSomethingBig();
//subordinate.doSomethingSmall(4);
}
You see, the method internally calls another method so it won't be intercepted and the output would look like this:
I do something big
Doing the cross cutting concern now
I did something small
I also do something small but with an int
You can by-pass this by doing that
public void doSomethingBig() {
System.out.println("I did something small");
//doSomethingSmall(4);
((CoreBusinessSubordinate) AopContext.currentProxy()).doSomethingSmall(4);
}
Code snippets taken from:
https://www.intertech.com/Blog/secrets-of-the-spring-aop-proxy/
The page doesn't exist anymore.