Допустим, мне нужно улучшить метод shower()
советом @MusicAround
, чтобы дать мне какую-нибудь музыку до и после выполнения метода shower()
.
public class Me {
@MusicAround
public void shower() {
// shower code omitted
}
}
Сначала я создал новую аннотацию @MusicAround
.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MusicAround {
Затем свяжите его с аспектом 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();
}
}
Настройте MusicAspect
как Bean
. @EnableAspectJAutoProxy
аннотация оставляет spring, чтобы инкапсулировать для меня прокси-сервер аспекта.
@Configuration
@EnableAspectJAutoProxy
public class ApplicationConfig {
// ... other beans omitted
@Bean
public MusicAspect musicAspect() {
return new MusicAspect();
}
}
В основном методе получите экземпляр Me
из контекста и выполните метод shower()
.
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
}
}
Теперь я могу включить музыку во время душа.
<hey jude>
I'm showering
<don't be so serious>
Проблема в том, что таким образом MusicAspect
класс соединяется с IPhone
классом. Я хочу разделить их, введя объект IPhone
в качестве параметра, как показано ниже:
@Aspect
public class MusicAspect {
@Around("@annotation(MusicAround)")
public Object musicAround(ProceedingJoinPoint joinPoint, IPhone iphone) throws Throwable {
iphone.music();
joinPoint.proceed();
iphone.music();
}
}
Конечно, здесь нельзя использовать второй параметр iphone в методе musicAround()
. Есть ли какие-либо пружинные функции, которые я могу использовать для разделения IPhone
и MusicAspect
в этом случае?
!Примечание: спасибо @kriegaex за корректуру.