Spring AOP capabilities - spring

i have a bean method : doXX (String a, String b)
And, i use this method in an other one
class Y {
X x;
...
doYY () {
....
x.doXX(A, B);
...
}
}
i want to change the paramters A, B to specific values
let's suppose that real values are : TEST, TEST
I want to set them always : TEST_en, TEST_en (i want to add "_en")
the method "doXX" is used a lot : so i don't want to change teh code source : it will take a lot of time.
Can i do it with AOP?
my container : Spring

What you are trying to do is not possible with Spring AOP because doYY and doXX are part of the same class. For the aspect to kick in, you need to call the method from another class. Check out the documentation for all the details

Response :)
Aspectj overwrite an argument of a method

Related

How can I manually evaluate the expression in a Spring #Value annotation?

My SpringBoot application has a bunch of #Value annotations. When the application is deployed to our Kubernetes cluster, it ends up using a properties file that is interpolated through a couple of different mechanisms. When it finally gets there, if developers make simple mistakes, the container can fail to start up, simply because they didn't set all the properties correctly. It's not easy to discover that this is what happened, until well after the mistake is made.
Note that virtually all of these #Value annotations will use the "${}" syntax, as opposed to "#{}". The primary concern is reading particular properties from a properties file, not Spring bean properties.
So, what I want to write is a little validation script (a small Java class), which does something like this:
Obtain the path to the generated properties file
Load that properties file into a Properties object
Scan the classpath for all classes (with a base package), and all fields in those classes, for #Value annotations
For each found #Value annotation, do some simple validation and evaluate the expression
If the validation or the evaluation fails, print an error message with all relevant details.
This script will run before the "kubectl rollout" happens. If we see these error messages before the rollout, we will save time diagnosing these problems.
I've been able to achieve everything so far except doing something with the loaded properties file and evaluating the expression. I know that Spring uses a bean postprocessor, but I don't know how I can manually call that.
Any idea how to fulfill that missing link?
Update:
I still don't have an answer to this.
I was thinking that perhaps the answer would be found in a BeanPostProcessor in the Spring codebase, so I cloned the spring-framework repo. I found a couple of potential ones, being "AutowiredAnnotationBeanPostProcessor", "BeanFactoryPostProcessor", "CommonAnnotationBeanPostProcessor", and "BeanPostProcessor", but I just don't see anything in any of these that looks like evaluating the expression in the Value annotation. I would have tried setting a breakpoint in the "value()" method of the annotation, but of course you can't set a breakpoint in a method like that.
Update:
To be clear, this expression is not a "Spring EL" expression. Those reference bean properties (or loaded properties) and begin with "#{". I'm working with expressions that just reference properties, which begin with "${". I did try parsing the expression with Spring EL, but it just thinks there's nothing there.
I've managed to figure this out. The key is the "PropertyPlaceholderHelper.replacePlaceholders(String, Properties)" method. Using that, I developed something like this:
PropertyPlaceholderHelper propertyPlaceholderHelper =
new PropertyPlaceholderHelper("${", "}", ":", true);
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
boolean foundAtLeastOneUnfoundProperty = false;
for (BeanDefinition bd : scanner.findCandidateComponents(basePackage)) {
String beanClassName = bd.getBeanClassName();
Class<?> clazz = Class.forName(beanClassName);
for (Field field : clazz.getDeclaredFields()) {
Value valueAnnotation = field.getAnnotation(Value.class);
if (valueAnnotation != null) {
Matcher matcher = propertyRefPattern.matcher(valueAnnotation.value());
if (matcher.matches()) {
String resultingValue = propertyPlaceholderHelper.replacePlaceholders(valueAnnotation.value(), properties);
if (resultingValue.equals(valueAnnotation.value())) {
// This means that the property was not found.
System.out.println("ERROR: Expression \"" + valueAnnotation.value() +
"\" on field \"" + field.getName() + "\" in class \"" + beanClassName +
"\" references a property which is not defined.");
foundAtLeastOneUnfoundProperty = true;
}
}
}
}
}

Where to put reusable pure functions in java?

I can't decide where to store reusable pure functions in Java. Example :
class ServiceA(){
private C pureFunction1(A a, B b) {
//code to produce C c;
return c;
}
}
class ServiceB(){
private C pureFunction1(A a, B b) {
//code to produce C c;
return c;
}
}
According to DRY i should extract this pure function somewhere.
I've considered to put it into following places :
Static helper class (smell + against SOLID's dependency inversion principle)
Spring bean (isn't it an overkill for just a pure function)
Super class (does not feel like a right thing for two independent services)
Interface with default method (Interfaces have different purpose)
Where would you recommend to put code for pureFunction1?
My preference would be for static helper class if there is no business logic involved in the method. For example, computing dates which don't have any business logic would be a right candidate for static helper class.
Spring bean can be an option if there is some proper business logic involved in the method
Having superclass may not be the right idea. Reasons here
I prefer static helper class. With java 8 you can declare static method in interface (and implement it in your services).
No difference between spring bean and static helper class for your case
Super class - not good idea without multiple inheritance feature.

Testing for sameness

BOOST_AUTO_TEST_CASE(testing_sameness) {
Dependency dep;
T foo(dep);
BOOST_CHECK_EQUAL(dep, foo.dep());
}
In a test like this, how to write the last line in order to test that the dep() method really returns the same object as injected over the constructor?
The underlying class should not implement additional methods like overloading the == operator.
Ideally, I would like to simply compare the addresses of both objects. The method is declared as:
Dependency dep() : const;
Writing this test is more for educational purposes, I wouldn't test getters like that in practice.

grails:spring:resources.groovy - is there any difference between refrencing beans with and without ref()

Help me with this small confusion as I am new to grails and working on grails with spring
Is there any difference between ref to firstBean in secondBean and thirdBean in resources.groovy
beans = {
firstBean(someclass)
secondBean(someotherclass) {
property = firstBean
}
thirdBean(someotherclass) {
property = ref(firstBean)
}
}
In your example there is hardly any difference. You are getting basically the objects you just have defined there. So this only works, if you can order your code, so this works and if the refs are right within your resources.groovy. The more common case is to use ref with strings, which may "forward reference". E.g.
beans = {
// fails! print b1
// fails! print ref(b1)
print ref("b1")
b1(Expando)
print b1
print ref(b1)
print ref("b1")
}
I'd use ref(<String>) for good measure, to give the underlying spring injection framework the easiest way to handle its dependencies (e.g. so components need only to be created, if and when they are needed).

JSTL Expression Language accessing object properties

I was following a tutorial today that had me scratching my head for an hour. Consider:
public class MyClass {
public int getTotal() {
amount = 100;
return amount;
}
}
and an excerpt from a JSP:
<p>Total: ${objectOfTypeMyClass.total}</p> //object instantiated elsewhere
Nowhere in the code was an instance variable named "total" ever declared or used. The only reference to the word "total" in the whole project (other than in the JSP) was the method getTotal().
So after some desperate last-ditch experimentation, it appears that Expression Language evaluates ${someObject.var} as "call the getVar() method of the someObject object.
I worked with this long tutorial for over a week thinking that ${someObject.var} was saying "directly fetch the saved instance variable "var" from someObject.
Did I have it wrong the whole time and is my observation correct that in order to reference any instance variable using EL, you have to provide a corresponding getter method named getVarname() where "Varname" is the name of the instance variable?
Also, EL seems to be case-insensitive in this regard. In my example above, "total" in ${objectOfTypeMyClass.total} is all lowercase where the method getTotal() has a capital "T".
And while we're at it, why don't we need to instantiate the variable "total"? I guess EL isn't actually referencing an instance variable...just a getter method?
What gives?
Did I have it wrong the whole time and is my observation correct that in order to reference any instance variable using EL, you have to provide a corresponding getter method named getVarname() where "Varname" is the name of the instance variable?
That's correct. EL adheres the JavaBeans specification as described in the EL specification.
Also, EL seems to be case-insensitive in this regard. In my example above, "total" in ${objectOfTypeMyClass.total} is all lowercase where the method getTotal() has a capital "T".
No, it's certainly not case insensitive. It's specified behaviour. ${bean.Total} would not have worked.
And while we're at it, why don't we need to instantiate the variable "total"? I guess EL isn't actually referencing an instance variable...just a getter method?
It's because it's supposed to adhere the Javabean specification.
All with all, read the both specifications and everything will be clear :)
See also:
What are the advantages of Javabeans?
The . in objectOfTypeMyClass.total is the JSTL EL Dot Operator. It can do a few different things. Including:
map.key accessed a value from map stored under key. or
object.property accesses property from object using "JavaBeans" conventions.
This should work:
public class MyClass {
private int total = 100;
public int getTotal() {
return total;
}
...
}

Resources