I am looking for a way to pass objects between Advice and JoinPoint, something like the following,
#Aspect
class SomeAspect {
#Around(execution * *.*(..) && #annotation(sample))
public Object PassbyRef(PJP pjp) {
SomeObjectToPass someObj = new SomeObjecttoPass();
Object retVal = pjp.proceed(someObj);
//process(someObj);
}
}
class UsingAspect {
#sample
public Object TestMethod() {
//how do I access someObj in this method?
}
}
I am looking to perform some action before execution of a method/JP, then I need to way to communicate between advice and method being executed, then I need to perform more actions after method has been executed.
Strange idea but if your design requires this You can try something like that:
just add a getter to your Advice class or maybe create an interface that requires this
class UsingAspect {
public getSomeObj(){return someObj};
}
and then from Aspect
if (joinPoint.getTarget().getClass() == UsingAspect.class){
UsingAspect ua=(UsingAspect)joinpoint.getTarget();
ua.getSomeObj()
}
Then in Advice and Aspect you should have reference to the same someObj. If you would like to do this in reverse direction just add a setter and save an object to your Advice class.
Related
i am kind of stuck on a problem with creating beans, or probably i got the wrong intention.. Maybe you can help me solve it:
I got a application which takes in requests for batch processing. For every batch i need to create an own context depending on the parameters issued by the request.
I will try to simplyfy it with the following example:
I receive a request to process in a batch FunctionA which is a implementation for my Function_I interface and has sub-implementation FunctionA_DE and FunctionA_AT
Something like this:
public interface Function_I {
String doFunctionStuff()
}
public abstract class FunctionA implements Function_I {
FunctionConfig funcConfig;
public FunctionA(FunctionConfig funcConfig) {
this.funcConfig = funcConfig;
}
public String doFunctionStuff() {
// some code
String result = callSpecificFunctionStuff();
// more code
return result;
}
protected abstract String callSpecificFunctionStuff();
}
public class FunctionA_DE extends FunctionA {
public FunctionA_DE(FunctionConfig funcConf) {
super(funcConf)
}
protected String callSpecifiFunctionStuff() {
//do some specificStuff
return result;
}
}
public class FunctionA_AT extends FunctionA {
public FunctionA_AT(FunctionConfig funcConf) {
super(funcConf)
}
protected String callSpecifiFunctionStuff() {
//do some specificStuff
return result;
}
}
what would be the Spring-Boot-Way of creating a instance for FunctionA_DE to get it as Function_I for the calling part of the application, and what should it look like when i add FunctionB with FunctionB_DE / FunctionB_AT to my classes..
I thought it could be something like:
PSEUDO CODE
#Configuration
public class FunctionFactory {
#Bean(SCOPE=SCOPE_PROTOTYPE) // i need a new instance everytime i call it
public Function_I createFunctionA(FunctionConfiguration funcConfig) {
// create Function depending on the funcConfig so either FunctionA_DE or FunctionA_AT
}
}
and i would call it by Autowiring the FunctionFactory into my calling class and use it with
someSpringFactory.createFunction(functionConfiguration);
but i cant figure it out to create a Prototype-Bean for the function with passing a parameter.. And i cant really find a solution to my question by browsing through SO, but maybe i just got the wrong search terms.. Or my approach to solve this issue i totally wrong (maybe stupid), nobody would solve it the spring-boot-way but stick to Factories.
Appreciate your help!
You could use Springs's application context. Create a bean for each of the interfaces but annotate it with a specific profile e.g. "Function-A-AT". Now when you have to invoke it, you can simply set the application context of spring accordingly and the right bean should be used by Spring.
Hello everyone and thanks for reading my question.
after a discussion with a friend who is well versed in the spring framework i came to the conclusion that my approach or my favoured solution was not what i was searching for and is not how spring should be used. Because the Function_I-Instance depends on the for the specific batch loaded configuration it is not recommended to manage all these instances as #Beans.
In the end i decided to not manage the instances for my Function_I with spring. but instead i build a Controller / Factory which is a #Controller-Class and let this class build the instance i need with the passed parameters for decision making on runtime.
This is how it looks (Pseudo-Code)
#Controller
public class FunctionController {
SomeSpringManagedClass ssmc;
public FunctionController(#Autowired SomeSpringManagedClass ssmc) {
this.ssmc = ssmc;
}
public Function_I createFunction(FunctionConfiguration funcConf) {
boolean funcA, cntryDE;
// code to decide the function
if(funcA && cntryDE) {
return new FunctionA_DE(funcConf);
} else if(funB && cntryDE) {
return new FunctionB_DE(funcConf);
} // maybe more else if...
}
}
Im looking into intercepting method invocations with Guice. I saw from here that basic interceptions are possible. However, the logic intercepting the methods require access to not only the parameters passed into the function, but also (unfortunately) a class member property. Is it possible to achieve this with Guice AOP? If so, what needs to be done? I'm thinking of something that might look like this:
class Foo {
#customInterceptor Object member; // Intercepting logic needs this
// function to be intercepted, param needed for the logic as well
#customInterceptor
void myFunc(#customInterceptor String param) {
// body, do something with member and param
}
}
It is possible using reflection. Not sure if it is a good practice and I assume you know what you are doing!
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object o = methodInvocation.getThis();
Field f = methodInvocation.getMethod().getDeclaringClass().getDeclaredField("member");
//if member is private
f.setAccessible(true);
System.out.println("inside interception :: " + f.get(o));
f.setAccessible(false);
return methodInvocation.proceed();
}
I am trying to learn AspectJ and figuring out how to retrieve specific joinpoints at certain points in a flow. My example is something like this:
I want to run an unit test annotated with JUnit's #Test then any methods called in that test that may be in another class annotated with another annotation, let's say #Example, then I could access basically the entire flow at those certain points so I had the ability to get the class name/method name of the test annotated with #Test and then also get the method information for the method annotated #Example. I've included some example code for clarification:
Test class:
public class ExampleTest {
#Test
public void shouldTestSomething() {
ExampleClass exampleClazz = new ExampleClass();
exampleClazz.something();
// ...
}
POJO:
public class ExampleClass {
#Example
public void something() {
// do something
end
end
So with these classes, I would like to make an aspect that would basically find any kind of #Example called within a #Test so I can then have access to both (or more) join points where I can grab the method/class signatures from the AspectJ JoinPoint object.
I tried something like this:
#Aspect
public class ExampleAspect {
#Pointcut("execution(#org.junit.Test * *(..))
&& !within(ExampleAspect)")
public void testPointCut() {}
#Pointcut("#annotation(com.example.Example)")
public void examplePointCut() {}
#After("cflow(testPointCut) && examplePointCut()")
public void doSomething(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature());
}
}
But the output looks like this:
void ExampleTest.ExampleClass.something()
The main issue is that it is missing the name of the test method (shouldTestSomething()) in the signature. What would be the best way to retrieve that?
Not sure if I understand correctly, but if you need to access information about the context from where a piece of code under a join point of your interest gets called, then what you need is the thisEnclosingJoinPointStaticPart (in native AspectJ syntax). If you are using AspectJ 5 annotation style aspects, just add a parameter to your advice method with the type JoinPoint.EnclosingStaticPart.
Note that this is not available for execution() style pointcuts, only for call() style pointcuts, otherwise the JoinPoint.EnclosingStaticPart and JoinPoint.StaticPart will be the same.
This means you need to rewrite your aspect in the following way:
#Aspect
public class ExampleAspect {
#Pointcut("execution(#org.junit.Test * *(..)) && !within(ExampleAspect)")
public void testPointCut() {
}
#Pointcut("call(#com.example.Example * *(..))")
public void examplePointCut() {
}
#After("cflow(testPointCut()) && examplePointCut()")
public void doSomething(JoinPoint joinPoint, EnclosingStaticPart enclosingStaticPart) {
System.out.println(joinPoint.getSignature() + " was invoked from "
+ enclosingStaticPart.getSignature());
}
}
The output with your test code would be:
void q35991663.com.example.ExampleClass.something() was invoked from void q35991663.com.example.ExampleTest.shouldTestSomething()
I also rewrote your examplePointCut. The pointcut expression #annotation(com.example.Example) would mean
any join point where the subject has an annotation of type com.example.Example
which would include both execution() and call() type join points. We need only the call() join points in this case, so #annotation() isn't even necessary if you are not planning to bind the value of the annotation to the advice context.
I write simple application. I don't want to use any frameworks. Please suggest me right place to hold annotation processing.
I have a few lines in main method:
String myString = (#NonNull String)list;
And I created #interface:
#Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public #interface NonNull {
}
Which step should I take next? Can I work with annotations without using reflection? Could you expose for me samples of such annotation processing code?
There is no way (AFAIK) to work with annotations without reflection.
If you don't want to use any framework, first step is to write kind of proxy class handling the method requests. It is an example of method processing with annotation use over method:
public class MyProxy {
private <T> T getProxy(T t) {
return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), new Class<?>[]{MyClass.class}, new MyInvocationHandler(t));
}
}
And then implement InvocationHandler:
public class MyInvocationHandler implements InvocationHandler {
private Object obj;
MyInvocationHandler (Object obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
boolean isNotNull = method.isAnnotationPresent(NotNull.class);
if (isNotNull) {
/* process annotated method. Or go through proxy object fields etc.. */
}
}
}
I hope it will help you.
You didn't say what kind of annotation processing you want to do.
Do you want to add a run-time check that will cause your code to crash if list is ever null at run time? For this, reflection will work.
Do you want to add a compile-time check that will reject your code if it cannot prove that list is never null at run time? For this, an annotation processor such as the Checker Framework will work.
Your question does not explain why you don't want to use a framework. Doing so will save you from re-implementing a lot of functionality that others have already created.
I have a problem where I am using #Around in two interfaces that are configured as Spring beans. One of those interface is a parameter to another interface and is always getting passed as null value. Following is the code snippet
public interface Interface1 {
public void method1();
}
public interface Interface2 {
public void method2(Interface1 param1);
}
#Around("execution(* Interface1.method1(..))")
private void interceptor1(ProceedingJoinPoint pJoinPoint) throws Throwable{
//do something
}
#Around("execution(* Interface2.method2(..))")
private void interceptor2(ProceedingJoinPoint pJoinPoint) throws Throwable{
//do something
}
In the calling code to Interface2 I always get the parameter param1 to method2 as null.
If I remove the #Around("execution(* Interface1.method1(..))") above it works fine. The reason for adding the #Around for both of them is to catch the Exceptions for logging and audit purpose and to stop the rest of the exceptions to be propagated.
Can you please help me around this problem?
It looks like your Aspects are flawed. An around aspect should always have a return type of Object not void. Returning void basically destroys the proper passing of return values from the callstack, remember that the around aspect puts code around your method execution!
So change your aspect to return object and always return the result of the call to proceed()
public Object aroundAdvice(ProceedingJoinPoint pjp) {
// Your stuff to do before the method call here
Object returnValue = pjp.proceed();
// Your stuff to do after the method call here
return returnValue;
}