Spring AOP - Pointcut Based on Value from Properties File - java

I'm working with Spring AOP and I'd like to be able to define a pointcut which is triggered whenever a method inside of a package, whose name is defined in a properties file, is called. That is, my pointcut would look something like
#Pointcut("within(${base.packageName}.*)")
public void MyPointCut() {}
and then if my config file had
base.packageName=foo.bar
then at runtime the pointcut would behave like this one
#Pointcut("within(foo.bar.*)")
public void MyPointCut() {}
I've tried several different things (e.g. using SpEL in the pointcut expression, configuring a class implementing the static pointcut interface) but nothing has worked.
Is there any way in spring to define a pointcut based on a value found in a configuration file?

This is not possible as the annotation value must be a compile time constant expression. So your pointcut cannot resolve ${} placeholder, as the placeholder resolution happens at runtime. See more here.

The fact that you cannot do this, may be by design.
I'm going to posit something to you here and I'd like you to think about the ramifications.
You are asking to be able to dynamically define a value to an Aspect Oriented construct. You are placing it in an externally accessible source that is un-validated. If a hostile, think in terms of security here, were to alter the point cut and execute some other piece of code (possibly even arbitrary) would you consider that safe?
AOP, while extremely valuable, puts most security researchers on edge.

Related

How to define a Pointcut to pick out all methods invoked by the specified method?

Is there any way to define a pointcut in AspectJ that would pick out each method directly executed by a specified method?
For example if there is a parentMethod() in classA that looks like:
public void parentMethod() {
classB.methodX();
classC.methodY();
}
I want to define a pointcut that uses just the information about parentMethod to pick out whenever its invoked methods, methodX() and methodY(), are executed. Is there a way to achieve this using AspectJ pointcuts?
I think we are not talking about inheritance, so you should not call it a "parent method". You simply mean a method calling other methods, do you not? Anyway, concerning your question:
With Spring AOP you have limited means of expressing control flow pointcuts, compared to native AspectJ's cflow() and cflowbelow() pointcuts. In your case and if you want to stick with proxy-based Spring AOP, a ControlFlowPointcut might be enough, because you do not need any method name patterns but seem to have a fixed method name as your target. For more information, see:
Section "update 2" of this answer for basic pointers to resources concerning ControlFlowPointcut.
This answer, if you want to match method patterns with a custom MultiMethodControlFlowPointcut (currently still unsupported by Spring out of the box).
Spring manual chapter "Using AspectJ with Spring Applications" explains how to configure Spring to use native AspectJ via load-time weaving (LTW).
If you decide to go the native AspectJ LTW way, the AspectJ manual section about control-flow-based pointcuts briefly explains cflow and cflowbelow.

Can I declare advice for surrounding an advice itself in aop java?

I have made an annotation(#MethodLogger) and written an aspect over it which basically logs the timing of the method and keep storing it. So on any method on which i put that annotation it works fine
But in a special use case I need to monitor an advice itself:
eg:
#MethodLogger
#Around("some function specified")
public Object method(ProceedingJoinPoint pjp) throws Throwable{
// code here
}
But this thing does not works. It never invokes my annotations aspect.
This does not work in Spring AOP, as is documented here:
Advising aspects with other aspects?
In Spring AOP, it is not possible to have aspects themselves be the target of advice from other aspects. The #Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.
If you want to do this, you need to activate full AspectJ via LTW in Spring. Then you can target advices directly if you know their method name. There even is a special pointcut designator adviceexecution() if you generally want to limit pointcut matching to advice execution or exclude the latter from matching via !adviceexecution(). For more details please check the AspectJ documentation.

How to understand annotation in java And How to implement my annotation in java?

What I have known are:
annotation was added in java 5
annotation can be using in method, class, and property
annotation can work in RUNTIME, CLASS, SOURCE( I don't know how to work with CLASS and SOURCE, and their's features)
annotation with retention which is RUNTIME can be implement when java program is running.
And I want to implement a annotation to have follows features:
ensure class only being allowed to create a instance
ensure methods only being allowed to access method in the class
it is like as friend in c++
it is same as public and private , but more dynamicall, like
#MyAnnotation(allowMethods={xxx.doSomething})
public void getValue(){}
the getValues method only can be accessed in the instance self and xxx.doSomething() method
What should I do and learn in next?
And Where can I learn about these?
I think you might be misunderstanding something there. Annotations are descriptive elements, not parts of your program. You can write as many annotations as you want, and people who use your code will still be able to ignore them.
That said, an annotation that enforces a policy (as yours does) can actually be implemented, either at compile or at runtime, but you need an external mechanism to help you. I can think of 3:
Annotation processing lets you interact with the compiler and process annotations by generating code or by omitting compiler errors. Unfortunately, I don't think it will work for your case, as you want to protect your annotated type from instantiation, and that means the call site doesn't actually have an annotation. Annotation processing only gives you access to the actual code pieces that have annotations, not to those that refer to them.
AspectJ allows you to write policy enforcement aspects and omit compiler errors, based on static pointcuts. The problem here is that static pointcuts have very limited semantics, so while you could forbid the instantiation of your class altogether, or from certain packages, you could not limit the your class instantiations to 1.
The third way, and probably the only sane way is that you use a container like Spring or Guice and configure your class as singleton. As long as you only retrieve your class from the container, it will never create a second instance.
Finally: If you want to limit the number of instantiations of your class, you can always use a classic Singleton pattern approach.

Aspectj around advice for field and class initializaton

Im implementing kind-of monitoring framework for my application. Basic idea is to use Aspectj to weave a piece of code that exposes variable anotated with certain annotation via JMX.
So i use pointcut
#Around("get (#mypackage.Gauge * *) && #annotation(annotation)")
However, in order to get my variable exposed via JMX i need to get it's value once (so that JMX binding occur). I use compile-time weaving. Is there any way that i can execute a certain piece of code once the class with #Gauge annotation is loaded?
Is there any way that i can execute a certain piece of code once the
class with #Gauge annotation is loaded?
Yes. Try this:
after() : staticinitialization(#Gauge *) {
// Do something here
}

AspectJ pointcut on method variable, is it possible?

I have been using AspectJ for a while and it works great on object scope fields containing annotations. I just ran into a situation where I want to annotate a variable of method scope that will work with my pointcut but I am having trouble with it.
Here is the pointcut that I am using. It works fine if my variable is a field for the object, but if I reduce the scope to a method (variable declared inside the method), then it doesn't work anymore and I am not sure why. Let me know what I can do, thanks.
after(final Trigger trigger): set(#Triggereable * *) && args(trigger)
{
System.out.println("trigger flush");
}
Also, here is an exmaple of what I want to work. That System.out.println above should fire when the Trigger is instantiated:
public void foo()
{
#Triggereable
private Trigger trigger = new Trigger();
}
If you came to such situation, you probably trying to change implementation instead of applying actual cross cutting concerns. Basically, it is not what AOP and AspectJ is supposed to be used for.
As a work around, you can either extract relevant functionality into a separate method and then apply your aspects to that method or alternatively, you can replace an entire method with that local variable, using around advice.
More over, in your particular example, the pointcut can be applied to the constructor execution within scope of a given method, so you can do practically the same thing without binding to a local variable.
AspectJ does not currently support pointcuts on local variables (read the FAQ entry).
I seem to recall a recent discussion about such a feature possibly added soon, but I could not find it in the AspectJ issue tracker nor in the Mailing List archives

Categories

Resources