AspectJ : Issue when combining multiple pointcuts in #Around advice - aop

I'm a beginner in AspectJ so please guide me to resolve the issue happening as per the below approach.
#Aspect
public class TestAop {
#Pointcut("execution(public * com.packg.foo.ClassOne.*(..))")
public void fooPoint()
#Pointcut("execution(public * com.packg.cat.ClassTwo.*(..))")
public void catPoint()
#Pointcut("execution(public * com.packg.roo.ClassThree.*(..))")
public void rooPoint()
#Around("fooPoint() || catPoint() || rooPoint()")
public Object myAdvice(ProceedingJoinPoint joinPoint) {
//do something like joint proceed and all
}
When it is not working ?
If I combine all the three pointcuts with OR .
When it is working ?
If i keep only two pointcuts it is working.
Am I vioalating any rules of #around advice. Is it possible to have multiple execution/pointcuts?
Hoping for the answers...

I had same problem but better solution IMO is(works for me):
#Aspect
public class TestAop {
#Pointcut("execution(public * com.packg.foo.ClassOne.*(..)) || execution(public * com.packg.cat.ClassTwo.*(..)) || execution(public * com.packg.roo.ClassThree.*(..))")
public void fooPoint(){}
#Around("fooPoint()")
public Object myAdvice(ProceedingJoinPoint joinPoint) {
//do something like joint proceed and all
}

I have solved the above issue by creating different advice for each pointcut.
I just found an alternate solution, but i'm still not convinced with that.
#Aspect
public class TestAop {
#Pointcut("execution(public * com.packg.foo.ClassOne.*(..))")
public void fooPoint()
#Pointcut("execution(public * com.packg.cat.ClassTwo.*(..))")
public void catPoint()
#Pointcut("execution(public * com.packg.roo.ClassThree.*(..))")
public void rooPoint()
#Around("fooPoint()")
public Object myFooAdvice(ProceedingJoinPoint joinPoint) {
//do something like joint proceed and all
}
#Around("catPoint()")
public Object myCatAdvice(ProceedingJoinPoint joinPoint) {
//do something like joint proceed and all
}
#Around("rooPoint()")
public Object myRooAdvice(ProceedingJoinPoint joinPoint) {
//do something like joint proceed and all
}

Related

Aspect not work with enhancerBySpringCGLIB

Faced with problem. Some fields in my classes are injected and in debugger i can see something like this:
Problem begins when I am trying to map #Aspect to one of methods defined in SettingService. Like this:
#Aspect
public class SettingsAspect
{
#AfterReturning(pointcut = "execution( * package.SettingsService.method(..))", returning = "result")
public void profilingSettingsAdvice(JoinPoint joinPoint, String result)
{
System.out.println(joinPoint.getArgs());
}
}
My service looks like this:
#Service
#Transactional
public class SettingsService
{
#Cacheable(value = "DefaultSettingsCache", key = "#root.methodName")
public int method()
{
return 1;
}
}
Don't know why, aspect isn't called after method() execution. Mystery is that aspect works ok with other classes/ What does it mean when class is injected with type Blablabla$$EnhancerBySpringCGLIB?
Thank you.
Your advice only matches methods returning a String, but your method returns an int.

Intellij reports code duplication while actually it's not

Here's the code. The code in method test and test2 are different because the parameter passed to Test constructor are different. Actually, if I change any parameter to null, intellij stops reporting the duplication. Is there any way to fix this?
---- Updated --------
I pass 2 functions doing totally different things but intellij still reports duplication
public class TestMain {
public void test(int a)
{
System.out.println("haha");
System.out.println("hahaa");
TestMain testMain = new TestMain();
new Test(testMain::test3);
System.out.println("hahaaa");
}
public void test2(int a)
{
System.out.println("haha");
System.out.println("hahaa");
TestMain testMain = new TestMain();
new Test(testMain::still_dup);
System.out.println("hahaaa");
}
public void test3(int a) {
System.out.println("abc");
}
public void still_dup(int a) {
String b = "edf";
b.toLowerCase();
}
public class Test {
Test(handler h) {
}
}
public interface handler<M> {
void entitySelector(int a);
}
public static void main(String[] args) {
TestMain test = new TestMain();
test.test(1);
System.out.println("-------");
test.test2(2);
}
}
I think the best way to fix this is to replace test and test2 by a single method. You don't have to distinguish what to pass the constructor because it's the current method. This might be the reason why code duplication is reported. The methods can be replaced by a single one without problems.

how to pass context arguments to advice in spring aop

I am learning spring aop now,and I have no idea to pass context arguments to the advice.
Note I mean the context arguments,not the normal arguments.
It is simple to pass the normal arguments,for example:
a join point:
public void read(String something){
}
#Aspect
public class SessionAspect {
#Pointcut("execution(* *.*(String)) &&args(something)")
public void sess() {
}
#Before("sess()")
public void checkSessionExist(String something) {
//Here
}
}
Then the something argument will be passed to the the advice checkSessionExist.
But how about I want to get the context arguments like HttpSession or something else?
a join point:
public void listUser(){
dao.list(User.class,.....);
}
#Aspect
public class SessionAspect {
#Pointcut("execution(* *.*(String))")
public void sess() {
}
#Before("sess()")
public void checkSessionExist(String something) {
//Here
}
}
In this example,the listUser join point is only allowed for logined user.
So I want to check if there is a identify in the current HttpSession,so I need to get an instance of HttpSession at the advice checkSessionExist.
But how to get it?
The simplest way is to add the HttpSession argumets to all the joit points like this:
public void listUser(HttpSession session){
dao.list(User.class,.....);
}
However this have gone against the AOP it self. In my opinion,the join point even does not need to know the exist of the Aspect,isn't it?
How to fix it ?
Instead of passing HttpSession via #Pointcuts, you could fetch HttpSession reference in the #Aspect itself
RequestContextHolder.currentRequestAttributes()
.getAttribute("user", RequestAttributes.SCOPE_SESSION)
#Aspect
public class SessionAspect {
// fetch the current HttpSession attributes and use as required
private ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
#Pointcut("execution(* *.*(String))")
public void sess() {
}
#Before("sess()")
public void checkSessionExist(String something) {
//Here
}
}

C# OO Design: case when only ONE abstract method is needed

I have 2 classes that have the exact same logic/workflow, except in one method.
So, I created a abstract base class where the method that differs is declared as abstract.
Below is some sample code to demonstrate my design; can anyone offer suggestions on a better approach or am I heading in the right direction.
I didn't use an interface because both derived classes B and C literally share most of the logic. Is there a better way to do what I am doing below via dependency injection?
public abstract class A
{
public void StageData()
{
// some logic
DoSomething();
}
public void TransformData();
public abstract DoSomething();
}
public class B : A
{
public override void DoSomething()
{
// Do Something!
}
}
public class C : A
{
public override void DoSomething()
{
// Do Something!
}
}
There is nothing wrong with what you have done. To introduce dependency injection into this design would be messy and overkill - you would have to pass in a delegate:
public class ABC
{
public ABC(Action z)
{
_doSomethingAction = z;
}
public void DoSomething()
{
_doSomthingAction.Invoke();
}
private Action _doSomthingAction;
}
There would be few reasons why you want to use this approach - one would be if you needed to execute a callback. So stick with the pattern you have, don't try to overcomplicate things.

OO design problem

Suppose there's 2 classes : A and B.
A can operate on B.
I need to be able to query all B instances that A has operated on.
And for a specific B instance, I need to be able to query all A instances that have operated on it.
What's the elegant(in the OO taste..) solution for this kind of problem?
In a language like Java I would do something like:
package com.whatever.blah;
public class A {
private Set<B> patients = new HashSet<B>;
public void operateOn(B patient) {
patient.startRecoveringFromOperation(this);
patients.add(patient);
}
public List<B> getPatients() {
return patients;
}
}
public class B {
private Set<A> surgeons = new HashSet<A>;
//this has package access to `A` can access it but other classes can't
void startRecoveringFromOperation(A theSurgeon) {
surgeons.add(theSurgeon);
}
public List<A> getSurgeons() {
return surgeons;
}
}
This really isn't doing anything special, beyond using package access to allow A access to B's startRecoveringFromOperation() method while hiding the method from most other classes. In other languages you might use a different approach to accomplish this. For instance in C++ you might declare A as a friend of B instead.
import java.util.*;
class A {
void operate(B b) {
operatedOn.add(b);
b.operatedOnBy.add(this);
}
final Set<B> operatedOn = new HashSet<B>();
}
class B {
final Set<A> operatedOnBy = new HashSet<A>();
}
public class Main {
public static void main(String[] args) {
A a=new A();
B b=new B();
a.operate(b);
System.out.println(a+" "+a.operatedOn);
System.out.println(b+" "+b.operatedOnBy);
}
}