static pointcut evaluation when it is done - spring

Spring AOP weaving process is done at runtime when the request to that specific method is made then a new proxy object will be created which wraps your current object and the call is intercepted.
Am I correct with my assumption?
Second thing is if this process is runtime then what are static pointcuts? when these pointcuts are evaluated?

Your understanding is wrong. A proxy is created only once at startup of the application not each time a method is called on an object. (Unless you have an AOP Scoped Proxy which is prototype scoped, but that scenario is highly unlikely).
#Aspect
public MyAspect {
#Pointcut("execution(* foo.bar.MyService.foo(..)) and args(x, ..)"
public Object around(ProceedingJoinPoint pop, MyObject x) { ... }
}
Given the aspect above the execution(* foo.bar.MyService.foo(..)) is the static part of the joinpoint, it can be matched regardless of inspection of types. The args(x, ..) however is dynamic as it needs to be determined at runtime if the value for x (the first argument in this case) is of type MyObject.
That part cannot be determined statically but only during the actual invocation. Basically anything that depends on runtime informations is dynamic in nature.

Related

Spring Boot application.properties appear unregistered when accessed from constructor

This is the code that I have:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
public Program() {
System.out.println(appTitle);
}
}
The application.properties has
app.title=The Program
The output is null insteaf of The Program.
So, what am I missing? I have tried several examples; none worked.
Since appTitle is an autowired field, it is not set until after the object is initially constructed. This is why the value is still null in your example. The bean construction process in this scenario is as follows:
The Program constructor is called, creating a new Program instance
The appTitle field is set on the newly constructed bean to ${app.title}
The ideal fix for this depends on your goals. If you truly need the value within the constructor, you can pass it in as an autowired constructor parameter. The value will then be available within the constructor:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
public Program(#Value("${app.title}") appTitle) {
System.out.println(appTitle);
}
}
If you don't need it in the constructor itself, but need it for the proper initialization of the bean, you could alternatively use the #javax.annotation.PostConstruct annotation to make use of it after the object's construction but before it is made available for use elsewhere:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
#PostConstruct
public void printAppTitle() {
System.out.println(appTitle);
}
}
Finally, if you don't need the value at construction time, but need it during the life of the bean, what you have will work; it just won't be available within the body of the constructor itself:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
}
Nothing wrong, just don't do it in a constructor...
Other answers on this question are written assuming the goal is creating a Spring-managed bean that uses the given property in its creation. However, based on your comments in another answer, it looks like the question you want answered is how to access an externalized property (one provided by #Value) within a no-argument constructor. This is based on your expectation that a Java inversion of control (IoC) container such as Spring should allow accessing externalized properties (and presumably other dependencies) within a no-argument constructor. That being the case, this answer will address the specific question of accessing the property within a no-argument constructor.
While there are certainly ways this goal could be achieved, none of them would be idiomatic usage of the Spring framework. As you discovered, autowired fields (i.e. fields initialized using setter injection) cannot be accessed within the constructor.
There are two parts to explaining why this is. First, why does it work the way it does, programmatically? Second, why was it designed the way it was?
The setter-based dependency injection section of the Spring docs addresses the first question:
Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.
In this case, it means that first the object is created using the no-argument constructor. Second, once the object is constructed, the appTitle is initialized on the constructed bean. Since the field isn't initialized until after the object is constructed, it will have its default value of null within the constructor.
The second question is why Spring is designed this way, rather than somehow having access to the property within the constructor. The constructor-based or setter-based DI? sidebar within the Spring documentation makes it clear that constructor arguments are in fact the idiomatic approach when dealing with mandatory dependencies in general.
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. [...]
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. [...]
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. [...]
A property needed to construct the object certainly would be categorized as a mandatory dependency. Therefore, idiomatic Spring usage would be to pass in this required value in the constructor.
So in summary, trying to access an application property within a no-argument constructor is not supported by the Spring framework, and in fact runs contrary to the recommended use of the framework.

#PostConstruct fails silently on a Grails Service

I thought the Spring annotations were supposed to work out of the box in a Grails environment, but I cannot get it to work at all. I also tried the afterProperties method, which did not work either.
Can anyone spot a mistake? Is there some configuration I need to do?
package dashboard
import javax.annotation.PostConstruct
class EmailJobSchedulerService
{
def grailsApplication
#PostConstruct
def init() {
def cronExpression = grailsApplication.config.emailAt8AmTrigger
println(cronExpression)
EmailSubscribersJob.schedule(cronExpression, new HashMap())
}
}
Try changing it to
#PostConstruct
void init() {
(i.e. void instead of def). I'm not sure whether Spring specifically enforces this but the specification of #PostConstruct states that among other things "The return type of the method MUST be void".
Edit: uchamp's comment is correct, I just tried the same test and indeed the #PostConstruct annotated method is called only the first time the service bean is used and, not necessarily immediately at startup. You can add
static lazyInit = false
to the service class to force it to be initialized eagerly at startup. This doesn't appear to be documented in the user guide, I deduced it by reading the code.
Note that "used" in the previous paragraph doesn't necessarily mean you have to call a method on it. The service bean will be initialized the first time it is fetched from the application context, either directly or because it has been autowired into another bean that is being initialized. For example, injecting the service into BootStrap using
def emailJobSchedulerService
would be enough to fire the #PostConstruct method, you don't have to actually call any of the service's methods from the BootStrap.init closure. Similarly, if your service were injected into any controllers then the init would fire the first time one of those controllers handled a request (any request, it doesn't have to be an action that calls the service).
Just adding on the answer from #Ian - For some reason i had:
#PostConstruct
private void init() {
This also failed silently and gave strange behavior. Solution was to remove "private":
#PostConstruct
void init() {

Spring Custom Scoped Bean - Destruction Callback

I have created a custom scope in my application that implements org.springframework.beans.factory.config.Scope.
As part of this, i have to implement the method below so that the PreDestroy method gets correctly invoked on my custom scoped beans.
public void registerDestructionCallback(String name, Runnable callback) {
}
The javadocs on the method are not that clear and I seem to be lost about what code i should write in that method.
Can someone please help?
It depends on what your custom scope actually does and if you are using this scope for DisposableBean, beans with destroy-method, and DestructionAwareBeanPostProcessor.
In simplest case you don't need to do anything or just log a warning that callback is not supported.
In more complex case, you need to handle object destruction that is outside of regular custom scope life cycle. Eg. when object is destroyed, based on its expiration or something similar (unlike explicit call to Scope.remove(String name) method).
For example, for session-scoped beans, this callback is hooked up to HttpSessionListener.sessionDestroyed(..) event. See sources for org.springframework.web.context.request.SessionScope class.

Calling AOPContext.currentProxy() from static method

I am using Spring's AOPContext.currentProxy() in a #service class implementation. However, i am using it in a static method and I do something like
public static void addCustomer() {
//....
((CustomerService) AopContext.currentProxy()).addCustomer();
//...
However, I am getting the error -- "cannot find proxy" set expose-proxy to true.
Is using static method the reason for this kind of error?
Note: "addCustomer" method is also static
Thanks in advance.
Proxy configuration is injected at the time of the instance creation. Suppose Using this proxy created instance you are calling to the method AOP is applicable to that method. Suppose without proxy instance or using class name ( in the case of static ) you are calling to the method it is direct call proxy config is not injected to the instance, So AOP is not applicable to that method call.
I'm not sure what you are trying to do, but you cannot do it this way at all.
Invocations of static methods are resolved at compile time, therefore they cannot be affected by proxy-based AOP. In other words:
AopContext.currentProxy() inside a static method doesn't make sense (unless you want to get a proxy for enclosing call of some instance method), because invocation of static method is not proxied
Calling a static method on an instance returned by AopContext.currentProxy() doesn't make sense, because it's resolved at compile time using a static type of expression, i.e. it compiles into CustomerService.addCustomer().
Does your configuration include something like <aop:config expose-proxy="true" />?

Spring AOP superclass method execution without #target

Consider the following situation:
class A() {
void a();
}
#MyAnnotation
class B extends A {
void b();
}
I want to advice all methods of all classes annotated with #MyAnnotation (i.e B.a()).
That's pretty easy task due to the possibility of using #target pointcut expression.
BUT! in that case all beans in a container (even unsuitable) will be Proxified what is unacceptable.
Now the question: Is it possible to build up pointcut expressino without #target but with the same effect?
You can use within like this.
execution(* *(..)) && within(#MyAnnotation *)
refer to https://stackoverflow.com/a/2522821/672586 and http://forum.springsource.org/showthread.php?28525-Difference-between-target-and-within-in-Spring-AOP for more details. The relevant section from the forum post explaining the difference between within and target
One difference between the two is that #within() is matched statically, requiring the corresponding annotation type to have only the CLASS retention. Whereas, #target() is matched at runtime, requiring the same to have the RUNTIME retention. Other than that, within the context of Spring, there is no difference between the join points selected by two.

Resources