Хобрук: Ваш путь к мастерству в программировании

Как передать объект в качестве параметра пружинному аспекту?

Допустим, мне нужно улучшить метод 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 за корректуру.


  • Этот вопрос страдает от проблемы XY: он объясняет, как вы технически придумываете для достижения свою цель вместо того, чтобы объяснять, чего вы на самом деле хотите достичь. Пример кода не подходит для объяснения вашей цели, как и ваше объяснение. Аннотация — это просто аннотация, она ничего не делает. Аспект что-то делает. Чего бы вы добились, внедрив что-то в аннотацию, что бы это ни значило? Пожалуйста, отредактируйте и улучшите свой вопрос. Спасибо. 02.05.2021
  • @kriegaex теперь выглядит лучше? 02.05.2021
  • stackoverflow.com/ вопросы/9633840/ 02.05.2021
  • Спасибо, тег @k-wasilewski @Autowired решил мою проблему. 02.05.2021

Ответы:


1

Проблема решена с помощью @k-wasilewski и @kriegaex. Спасибо, бро.

Ответ: аннотация @Autowired.

Определите IPhone как поле класса MusicAspect. Добавьте тег @Autowired, который указывает контексту Spring инициализировать для нас экземпляр IPhone.

@Aspect
public class MusicAspect {

    @Autowired
    private IPhone iphone;

    @Around("@annotation(MusicAround)")
    public Object musicAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Iphone.music();
        joinPoint.proceed();
        iphone.music();
    }

}

Не забудьте зарегистрировать бин IPhone в ApplicationConfig. Остальная часть остается прежней.

@Configuration
@EnableAspectJAutoProxy
public class ApplicationConfig {
    // ... other beans omitted

    @Bean 
    public IPhone iphone() {
        return new IPhone();
    }
}

Код прошел модульное тестирование на моем ноутбуке.

02.05.2021

2

Это предварительный ответ, потому что содержание не подходит для комментария.

При просмотре кода в вашем обновленном вопросе некоторые вещи кажутся мне странными:

  • Интересно, почему все так стремятся всегда использовать аспекты в сочетании с аннотациями. Почему бы не использовать pointcut, который непосредственно нацелен на интересующие пакеты, классы или методы? Все это загрязнение аннотаций ужасно, если не абсолютно необходимо. В идеале код приложения должен быть полностью независимым от существования аспектов.
  • Вы неправильно используете указатель pointcut @annotation. Вместо @annotation(@MusicAround) должно быть @annotation(MusicAround). Но также это работает только в том случае, если аннотация находится в том же пакете, что и аспект, в противном случае вам понадобится @annotation(fully.qualified.package.name.MusicAround).
  • Вы используете MusicAspect, но затем объявляете bean-компонент MinstrelAroundAdvice. Это не похоже на совпадение. Кроме того, аспект есть аспект, а метод внутри него, который действительно что-то делает, — это совет. Таким образом, имя класса *Advice для аспекта просто неверно. Вместо этого лучше использовать *Aspect или что-то еще, что правильно описывает, что делает аспект. В этом случае MusicAspect мне кажется вполне подходящим.

Теперь, что касается вашего фактического вопроса, мне все еще неясно. Речь идет о том, как внедрить (автоматически подключить) другой компонент в экземпляр аспекта?

Конечно, мне не разрешили это сделать.

Почему конечно? Что не разрешалось? Как вы заметили? Что-то не получилось? Вы получили сообщение об ошибке? Трассировка стека? Пожалуйста, четко объясните, что вы пробовали, каков ожидаемый результат и что вместо этого произошло. Сделайте вашу проблему воспроизводимой. Ваши фрагменты кода этого не делают, к сожалению. Просто представьте на минуту, что кто-то другой задаст вам тот же вопрос, а вы не увидите полный код и другую контекстную информацию, необходимую для понимания проблемы. Не могли бы вы ответить на него? Если ваши помощники не понимают проблемы, как они могут ответить на ваш вопрос? Рекомендуем узнать, что такое MCVE.

02.05.2021
  • Выражение Pointcut не является гибким и сложным в использовании. Добавление аннотаций везде, где мы хотим, выглядит более интуитивно понятным. Загрязнение? Вы думаете, что длинное выражение pointcut, такое как @Pointcut("execution(public String com.baeldung.pointcutadvice.dao.FooDao.findById(Long))"), красиво? 02.05.2021
  • Его не сложно использовать, и он гибкий, потому что вы можете изменить его. Что еще более важно, вы можете использовать и поддерживать его в одном месте, не изменяя код вашего приложения потенциально в сотнях мест. Пользователи могут забыть добавлять аннотации, но специалист по сопровождению аспекта может убедиться, что аспект нацелен на нужные места. Во всяком случае, я только что упомянул об этом, потому что в вашем примере для новичков это слишком сложно. Настоящая проблема заключалась в синтаксической ошибке в вашем pointcut и в том факте, что вы не знали, как автоматически подключить компонент - последнее является основами Spring, а не связано с AOP. 03.05.2021
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..