При использовании @EnableAspectJAutoProxy не работает Autowired

139
30 октября 2019, 13:20

начал разбираться со Spring и AOP, хочу сделать логирование, но столкнулся с проблемой. Вот классы мои классы Application:

package ru.evgeny.start;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import ru.evgeny.quize.impl.Quize;
import ru.evgeny.quize.interfaces.IQuize;
@ComponentScan(basePackages = "ru.evgeny")
@EnableAspectJAutoProxy
@Configuration
@PropertySource("classpath:properties.properties")
public class Application {

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Application.class);
        context.refresh();
        IQuize quize = context.getBean(Quize.class);
        quize.start();
        quize.getResult();
    }
}

CsvQuestionLoader:

package ru.evgeny.quize.impl;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import ru.evgeny.answer.Answer;
import ru.evgeny.answer.CsvAnswer;
import ru.evgeny.question.impl.CsvQuestion;
import ru.evgeny.question.interfaces.IQuestion;
import ru.evgeny.quize.interfaces.IQuestionLoader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
public class CsvQuestionLoader implements IQuestionLoader {
    private static final String QUESTION = "question";
    private static final String ANSWER = "answer";
    private static final String POINT = "point";
    private static final char[] PREFIX = {'a', 'b', 'c'};
    private String path;
    @Autowired
    public CsvQuestionLoader(@Value("${csv.path}") String path) {
        this.path = path;
    }
    @Override
    public List<IQuestion> load() {
        List<IQuestion> questions = new ArrayList<>();
        CSVFormat csvFormat = CSVFormat.EXCEL.withHeader();
        try (CSVParser records = csvFormat.parse(new FileReader(path))) {
            for (CSVRecord record : records) {
                String question = record.get(QUESTION);
                List<Answer<Boolean>> answers = new ArrayList<>();
                for (int i = 0; i < PREFIX.length; i++) {
                    answers.add(new CsvAnswer(record.get(ANSWER + " " + PREFIX[i]), record.get(POINT + " " + PREFIX[i]).equals("1")));
                }
                questions.add(new CsvQuestion(question, answers));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return questions;
    }
}

Quize:

package ru.evgeny.quize.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import ru.evgeny.answer.Answer;
import ru.evgeny.question.interfaces.IQuestion;
import ru.evgeny.quize.interfaces.IQuestionLoader;
import ru.evgeny.quize.interfaces.IQuize;
import java.util.List;
@Component
public class Quize implements IQuize {
    List<IQuestion> questions;
    @Autowired
    public Quize(IQuestionLoader loader) {
        questions = loader.load();
    }
    @Override
    public void start() {
        questions.forEach(IQuestion::ask);
    }
    @Override
    @SuppressWarnings("unchecked")
    public void getResult() {
        int right = 0;
        for (IQuestion question: questions) {
            String questionName = question.getName();
            Answer<Boolean> answer = (Answer<Boolean>) question.getResult().get(question);
            if(answer.getPoint()) right++;
            System.out.println(questionName + "-" + answer.getName() + " " + answer.getPoint().toString());
        }
        System.out.println(right + "/" + questions.size());
    }
}

Проблема заключается в том, что при старте приложения я получаю следующий вывод в консоль:

Call method : load
Method load finish
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ru.evgeny.quize.impl.Quize' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:343)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1123)
    at ru.evgeny.start.Application.main(Application.java:25)

где за строчи:

Call method : load
Method load finish

отвечает мой аспект логирования:

package ru.evgeny.logging;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
    @Before("within(ru.evgeny..*)")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Call method : " + joinPoint.getSignature().getName());
    }
    @After("within(ru.evgeny..*)")
    public void logAfterReturning(JoinPoint joinPoint) {
        System.out.println("Method " + joinPoint.getSignature().getName() + " finish");
    }
}

Но если я уберу аннотацию @EnableAspectJAutoProxy то логирования естественно происходить не будет, но приложение работает нормально. И вот совершенно не могу понять почему при использовании @EnableAspectJAutoProxy Spring не может найти компонент Quize

Answer 1

Потому что нет такого Beana

Запомни никогда не доставай бины через имякласса.class

нужно через интерфейс.class

Точно не знаю как работает аннотация EnableAspectJAutoProxy, но подозреваю она проксирует все бины, и когда ты пытаешься достать бин он запроксирован

READ ALSO
Разные view для списка

Разные view для списка

Решил сделать в списке групировку по датам, что то подобное такому:

150
Закрыть listening порт

Закрыть listening порт

Мне нужно закрывать listening порт(например, 12000, который создается java методом serversocketaccept) в определённый момент(неизвестно когда он наступит)

154
&ldquo;Failed to instantiate java.util.List using constructor NO_CONSTRUCTOR with arguments &rdquo;

“Failed to instantiate java.util.List using constructor NO_CONSTRUCTOR with arguments ”

Вызов данного контроллера выдает ошибку:

260
Tomcat не запускает проект

Tomcat не запускает проект

Запускаю этот проект через Tomcat https://githubcom/CaymanJava/online_banking

135