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
Related
I have a question about Reflection, but the motivation is from using Spring Framework.
Consider this project, which is a sort of Minimum Working Example version of a deployed project.
In the ProjectionResourceProcessorConfig class, I have an entityProjectionResourceProcessor method for every projection, and every entity in the database have a few projections. That's about 60 methods.
I don't want to keep this up because of the obvious maintenance disadvantage. I want to use Reflection in order to automatically register one bean for every projection class.
The postProcessBeanDefinitionRegistry method in the ProjectionResourceProcessorConfig class shows that I can get the list of classes I want to use to register one bean for each and shows how to register a bean programatically.
However, because I need to use the ProjectionResourceProcessor class, I need to override the getEntityClass method. I haven't been able to find a way to do that programatically. That's why I've declared the inner class. It shows the programatic bean registration working, but it falls in the same issue as requiring a piece of code for every bean.
Apart from reflection, I tried to use the setMethodOverrides method of the RootBeanDefinition class to override that method, but I couldn't manage to understand how to use that method. Google couldn't find any documentation or usage example (except for a vaguely related Chinese post with copies on several different websites).
I also tried to use the MethodReplacer class but I haven't found how to use it with annotation driven configuration.
I also tried to replace the getEntityClass method by a variable and replace the variable's value by reflection, but apparently when the variable is read the value that was set in the super class is the one that is retrieved.
To test the project, run the tests at DemoApplicationTests. It will print the projection of some entities. If they have links, it's working.
Is it possible to do what I want? If it is, how?
Thanks in advance.
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.
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.
There is a pattern which is widely used in my current project:
private Collection<Converter<T>> converters = new HashSet<>();
#Inject
private void init(#Any Instance<Converter<T>> converters) {
for (Converter<T> converter : converters) {
this.converters.add(converter);
}
}
This way I can create as many converters as I want and they are automatically injected to my bean.
My problem is now with testing: the converters collection is used in my code, but Junit doesn't call the init(..) method and I need to call it to set the mocked converters.
I could make the method protected, but I don't feel OK with it because I would be changing the visibility scope of the method.
I could also call the method using reflection, but this also doesn't feel right.
This brings me to the conclusion that this code could be improved to be more testable.
Is there anyway I change this code so the testability is improved but the references are still automatically injected?
Just go ahead and make it 'public' or 'protected'.
You are not actually gaining any protection from someone changing the collection post-instantiation this way (you've just made it a little more awkward), so you don't lose anything by exposing that method (in fact I'd argue you make your class slightly better, because than you let people chose how they want to construct, rather than forcing a use of injection/reflection).
If you did want to fully prevent post-instantiation modification, than you're going to have to go to a 'final' variable anyway, with an unmodifiable collection type and change to constructor injection, but I don't get the impression that this is what you want to do.
Thing is: if you can't "trust" the people who can write code within your "package" ... I guess having "private" on a method doesn't really help you anyway. Because if people want to mess up, and they can write code in your package, they will find ways to mess up anyway.
Meaning: if you drop the "private" on your method, yes it becomes package-visible. But you can place a javadoc on it that says: "Don't call directly; used for unit test/auto-wiring only" or something like that.
I'd like to know how to - if even possible - reflect what method calls are executed inside the method during execution. I'm especially interested in either external method calls (that is, methods in other classes) or calling some specific method like getDatabaseConnection().
My intention would be to monitor predefined objects' actions inside methods and execute additional code if some specific conditions are met like some method is called with specific values. The monitor would be completely external class or a set of classes with no direct access to the object to be monitored by no other way than reflection.
Aspect J will solve your problem.
Try to define a pointcut like this:
pointcut profilling(): execution(public * *(..)) && (
within(com.myPackage..*) ||
In this way you will catch all the call to any public method within the package com.myPackage. Add as many within clauses you need.
Then add the following code:
Object around(): profilling() {
//Do wherever you need before method call
proceed();
//Do wherever you need after method call
}
IF you want to learn something more about aspectJ follow this guide.
I'd expect BCEL to be able to do this. From the web site:
The Byte Code Engineering Library is
intended to give users a convenient
possibility to analyze, create, and
manipulate (binary) Java class files
(those ending with .class).
The "analyze" part being the important bit here. The JavaDoc isn't visible on the web site (as far as I can see) so I can't easily be sure whether or not it'll help you, but it's a reasonable starting point.
BCEL should offer this capability, but ...
... your requirements sound a lot like Aspect-Oriented Programming (AOP), so you should probably also look at AspectJ (with Eclipse tooling).
The main advantage of AspectJ is that it offers a well-designed way to express your specific conditions.