Alias annotation for providing value to bean method parameter in another annotation - spring

I've been looking around the forum for solution that would implement this functionality, but couldn't find any I could understand. Is it possible to create an alias or through creating an processor an annotation, that will work as follows:
#myAnnotation("myvalue")
So that the underlying logic behind it would be:
#baseAnnotationFromSpring(property="some-static-value=#bean.method('my-value')")

Related

How to redefine Spring beans representation

I would like to add extra attribute to the internal representation of beans in Spring. Is it possible? What mechanism should be applied if any?
My goal is to define my own beans for my framework. I can do it from scratch or reuse Spring mechanisms.
You could have a look at the documentation Container Extension Points.
To achieve customization you can create a:
BeanPostProcessor bean which operates on a bean instance. For example this allows to create a custom bean registry, to proxify...
BeanFactoryPostProcessor which can operate on bean metadata. This allows for overriding or adding properties even to eager-initializing beans, modifying the class...
BeanDefinitionRegistryPostProcessor which can operate right after the registry initialization. This allows to create, remove or update beans definitions.
For example you can create a new BeanDefinitionRegistryPostProcessor which will register (or modify) beans using a custom implementation of BeanDefinition which will contain custom attribute based on for example your owns annotation.
Could you elaborate a bit what are you trying to achieve with your framework?
Merci beaucoup, Nicolas :)
I will study both your answer and the documentation you provided. I have already found the *Postprocessors you mentioned but I was not sure if this is the right place and what is the nature of their customizations (subclassing or something different) and what are the consequences. My problem is not as simple as I told (not just adding an attribute) - the extended Spring bean should be used also in cooperation to Spring+AspectJ (not SpringAOP), especially with declare-parents construct. I would like to be able to create proxies for the redefined beans as well. I will let you know what are the results of my investigation and may be I will ask some questions.
And the answer to all of you:
My framework is dedicated to defining graph modeling languages (meta-models) at run-time (being far extension of OMG standards) and I am looking for solutions of limits introduced by current object representation in JVM, which promotes behaviour over structure. This is one of several approaches, but the most prospective for me due to the relatively small effort.

getting bean id of target class in advice

I have a few classes that interact with databases (more than one). Some classes are reused so for example "obs.table1" is used to interact with table1 in database "obs" while "ref.table1" is used to interact with table1 in database "ref". These databases are at different URLs and each gets its own connection pool, etc... obs.table1 and ref.table1 are both instances of MyTable1Class, defined in beans file.
I have a pointcut that intercepts calls to methods annotated with #Transactional or with a custom annotation #MyTablesAnnotation and have it set so those calls will all get routed into a #Around advice.
This all works and the flow through the advice is correct.
What I am trying to add is reporting on what is going on in there. Currently I can tell where in there I am, but I can't tell if it was obs.table1 or ref.table1 object that got me there.
Is there a way to extract the bean id of the object on whose method the advice was invoked on?
ProceedingJoinPoint that is passed to the method the only thing I do with it is call a .proceed on it and the rest is just various checks and catches. I see that I can get either the target class or proxy class out of it, but... not sure how to go from there to knowing what the bean id was.
Is it possible?
Firstly it is not recommended to depend on bean id as it creates tight coupling with framework.
To quote from docs Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external configuration, as well as a possibly unnecessary dependence on a Spring API.
Now to answer your question yes it is possible to fetch the name of bean via org.springframework.beans.factory.BeanNameAware.
The class for which you require the bean name should implement it and spring will auto-magically inject the name of the bean. However there is a gotcha which you should be aware and is mentioned in docs here

Custom annotation like #Value

I need to create a means to add a custom annotation like
#Value("${my.property}")
However, in my case I need to get the value from a database rather then a properties file.
Basically I would like to create a bean on container startup that reads in property name value pairs from a database and can then inject these into fields belonging to other beans.
Approach #1:
One way is to create an Aspect, with a point-cut expression that matches any method having this annotation.
Your aspect will then:
Read the property value in the annotation
Look up the required value an inject it into the class.
AOP Kickstart
Here's a guide to getting started with AOP in Spring
http://www.tutorialspoint.com/spring/aop_with_spring.htm
Joinpoint matching
Here's a reference that describes how to create a join-point that matches on annotations: http://eclipse.org/aspectj/doc/next/adk15notebook/annotations-pointcuts-and-advice.html
Approach #2:
Another way is to use a BeanFactoryPostProcessor - this is essentially how a PropertyPlaceholderConfigurer works.
It will look at your bean definitions, and fetch the underlying class.
It will then check for the annotation in the class, using reflection.
It will update the bean definition to include injecting the property as per the value in the annotation.
. . actually I think approach #2 sounds more like what you want - all of the processing happens on "start-up". . . (In actual fact your modifying the bean recipes even before startup). . whereas if you used AOP, you'd be intercepting method invocations, which might be too late for you?
Namespace Handler
If you wanted you could even create your own Spring namespace handler to turn on your post processor in a terse way. Eg:
<myApp:injectFromDb />
as an alternative to:
<bean class="MyDatabaseLookupProcessorImpl etc, etc. />
Update: Approach #3
As of Spring 3.1 there's also the PropertySourcesPlaceholderConfigurer, that will provide most of the plumbing for you, so you can achieve this with less code.
Alternatively you should be able to configure kind of properties repository bean and then use it in SpEL directly in #Value annotation.
Let's say you'd have bean called propertiesRepository in your context that implements following interface:
interface PropertiesRepository {
String getProperty(String propertyName);
}
then on bean where you want to inject values you can use following expression
#Value("#{propertiesRepository.getProperty('my.property')}")
String myProperty;
You can use #Value annotation by injecting database configuration in application environment itself.
I know this is an old question but I didn't find an exact solution. So documenting it here.
I have already answered the same on different forum.
Please refer to this answer for exact solution to your problem.

Spring lookup method injection with parameters

Is there a way to use Spring lookup method inject with parameters? For example, I want to be able to instantiate prototype-scoped beans while passing them arbitrary parameters via constructor.
It looks like this vital feature was finally added in Spring 4.1.0.RC2. I have tested it and it seems to work.
It was added as part of JIRA ticket SPR-7431 ("Passing lookup-method arguments to created bean constructor"):
<lookup-method/> should allow specifying any number of parameters. These parameters should be passed directly to the constructor of the newly created bean.
For more info on how the feature was finally added, this blog post was written by the guy who opened the JIRA ticket.
You can inject them via field/setter injection. (Note that constructor injection is frowned upon by spring, although it's supported)
in short, no. Spring does support something called "method injection" but it's different than you're thinking. Spring also supports constructor injection, but then you're not calling the constructor yourself, Spring is, and wiring it itself.
Instead, you can use reflection to instantiate the class and pass arbitrary parameters yourself:
Class<MyObject> clazz = MyObject.class; // this can be looked up or stored in a field, etc.
MyObject myObject = clazz.getConstructor(String.class, int.class)
.newInstance("arbitrary parameter", 42);

SpringAOP-generated Dynamic subclass is missing annotation

I'm trying to use Spring AOP to inject behavoir into an object. The target object has a single method which is the join point for this new behavior. That method also has a custom annotation that I want to be able to read from other unrelated code. Because my class doesn't implement an interface, Spring is using CGLIB to dynamically subclass the target object. The generated subclass doesn't seem to have the annotation added to the original class.
I tried adding the #Inherited annotation to the custom annotation without luck. It turns out #Inherited only applies to classes. This suggests that Spring would have to explicitly apply my annotation to the overridden method in the subclass.
EDIT: I found a workaround and some more information on the problem. It looks like the CGLib people are aware of the issue. Annotations are treated like implementation in Java (rather than like part of the method signature). Overriding methods must re-declare annotations. CGLib doesn't do this (intentionally by the sound of things).
My workaround was to change my reflection logic. Where I was searching for the annotated method on the class passed to me, I now look at the class and it's super classes. I end up locating the method using the superclass (in the case of a proxy), but when I call the method, regular polymorphisim applies. This makes for some ugly reflection code (even more ugly than normal). It also seems like I shouldn't have to compensate for a SpringAOP implementation detail in my code.
It seems like Spring should provide a cleaner way to handle this. If anyone has other suggestions, they would be appreciated.
Are you sure you have the RetentionPolicy on your annotation set to RUNTIME ?

Resources