Let's say I need to enhance the shower() method with a @MusicAround advice to give me some music before and after executing the shower() method.
public class Me {
@MusicAround
public void shower() {
// shower code omitted
}
}
First I created the new annotation @MusicAround.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MusicAround {
Then bind it with an aspect MusicAspect.
@Aspect
public class MusicAspect {
@Around("@annotation(MusicAround)")
public Object musicAround(ProceedingJoinPoint joinPoint) throws Throwable {
IPhone iphone = new IPhone();
Iphone.music();
joinPoint.proceed();
iphone.music();
}
}
Configure MusicAspect as a Bean. @EnableAspectJAutoProxy annotation leaves spring to encapsulate the aspect proxy for me.
@Configuration
@EnableAspectJAutoProxy
public class ApplicationConfig {
// ... other beans omitted
@Bean
public MusicAspect musicAspect() {
return new MusicAspect();
}
}
In main method, get Me instance from context, and execute shower() method.
public static void main(String[] args) {
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Me me = context.getBean(Me.class);
me.shower();
context.close();
} catch (ApplicationContextException ace) {
// handle exception
}
}
Now I can enjoin the music during the shower.
<hey jude>
I'm showering
<don't be so serious>
The problem is that in this way MusicAspect class is coupled with IPhone class. I want to decouple them by injecting IPhone object as a parameter as below,
@Aspect
public class MusicAspect {
@Around("@annotation(MusicAround)")
public Object musicAround(ProceedingJoinPoint joinPoint, IPhone iphone) throws Throwable {
iphone.music();
joinPoint.proceed();
iphone.music();
}
}
Of cause a second parameter "iphone" in musicAround() method will not be allowed here. Is there any spring features that I can use to decouple IPhone and MusicAspect in this case?
!Note: thanks @kriegaex for the proofreading.