복붙노트

[SPRING] AspectJ와 Spring Boot에서 @Autowired 사용하기

SPRING

AspectJ와 Spring Boot에서 @Autowired 사용하기

"Aspect"에 @Autowired 주석을 사용하고 싶습니다. 내 측면에서 저장소를 주입하고 싶지만 autowired 클래스의 메소드를 호출하려고하면 NullPointException이 발생합니다.

@Aspect
public class AspectSecurity {

@Autowired
private UserRepository userRepository;


@After("execution(public * dash.*.*Controller.*(..))")
public void authentication(JoinPoint jp) throws UnauthorizedException {
    System.out.println("SECURITY !");

    System.out.println(userRepository.findAll().toString());

   }
}

이미 aspect 클래스 위에 @Component를 추가하려했지만 동일한 오류가 발생했습니다.

애스펙트 클래스를 사용하지 않고 @Controller를 사용하면 문제없이 저장소를 호출 할 수 있습니다.

일부 문서에서는 xml 파일을 사용하여 스프링 구성에 대해 설명하지만 스프링 부트에는 이러한 파일이 없습니다.

여기에 aspect.xml 플러그인을 호출하는 내 pom.xml의 일부가있다.

            <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.4</version>
            <configuration>
                <showWeaveInfo>true</showWeaveInfo>
                <source>1.6</source>
                <target>1.6</target>
                <Xlint>ignore</Xlint>
                <complianceLevel>${compiler.version}</complianceLevel>
                <encoding>UTF-8</encoding>
                <verbose>false</verbose>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>

여기 내 응용 프로그램 클래스 :

package dash;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

여기 aspect가 호출되는 Controller 클래스 :

package dash.user;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import dash.GenericController;



@Controller
@RequestMapping("/user")
public class UserController extends GenericController {

@Autowired
private UserRepository repository;

@RequestMapping("/findAll")
public @ResponseBody User create(
        @RequestParam(value="login", required=true) String login,
        @RequestParam(value="password", required=true) String password) {

    System.out.println(login);
    System.out.println(password);


    System.out.println("Users found with findAll():");
    System.out.println("-------------------------------");
    for (User user : repository.findAll()) {
        System.out.println(user);
    }


    return  repository.findOne("root");
    }
}

참고 : 이미 응용 프로그램 클래스 위에 @EnableAspectJAutoProxy를 추가하려고했습니다.

당신의 도움을 주셔서 감사합니다

해결법

  1. ==============================

    1.AspectJ 제직을 설정하는 것은 매우 까다 롭습니다. 그래서 여기 몇 가지 문제가있을 수 있습니다. @Aspect에서 @Component를 사용하지 않거나 적어도 @ComponentScan에서 제외되어 있는지 확인하십시오. 그 이유는, Spring과 AspectJ가 싱글 톤 인스턴스의 값에 동의하도록, 그 타입의 @Bean을 생성하고 AspectJ와 같은 생성 메커니즘을 명시 적으로 사용해야하기 때문이다. 올바른 방법은 @Bean 정의에서 Aspects의 정적 인 편리한 메소드를 사용하는 것입니다. 예 :

    AspectJ 제직을 설정하는 것은 매우 까다 롭습니다. 그래서 여기 몇 가지 문제가있을 수 있습니다. @Aspect에서 @Component를 사용하지 않거나 적어도 @ComponentScan에서 제외되어 있는지 확인하십시오. 그 이유는, Spring과 AspectJ가 싱글 톤 인스턴스의 값에 동의하도록, 그 타입의 @Bean을 생성하고 AspectJ와 같은 생성 메커니즘을 명시 적으로 사용해야하기 때문이다. 올바른 방법은 @Bean 정의에서 Aspects의 정적 인 편리한 메소드를 사용하는 것입니다. 예 :

    @Bean
    public AspectSecurity interceptor() {
        AspectSecurity aspect = Aspects.aspectOf(AspectSecurity.class);
        // ... inject dependencies here if not using @Autowired
        return aspect;
    }
    

    또한 컴파일 된 애스펙트가 AspectJ 위버 경로에 있는지 확인하려면 aop.xml이 필요하다. 그것은 당신이 Maven AspectJ 플러그인으로하고있는 것과 같을 수있다. 그러나 만약 내가 이것을했다면 아마 aop.xml을 수동으로 만들고, @EnableLoadTimeWeaving을 사용하고, 플러그인을 버린다. 당신은 아마 무슨 일을하는지에 따라 스스로 결정할 수 있습니다.

    애스펙트가 애플리케이션 컨텍스트를 구축하는 동안 사용되는 것을 가로 챌 필요가있는 경우 라이프 사이클 문제가 발생할 수도 있습니다. @Bean 메쏘드의 어떤 차단에 의존하지 않음으로써 그것을 피할 수 있습니다. 그렇지 않으면 @DependsOn으로 게임을 끝내서 특정 빈의 순서를 만들려고 시도 할 수 있습니다. 귀하의 앱이 아직 그로 고생하고 있는지 여부는 말할 수 없습니다.

    이전 (스프링 부트 1.3에서는 사용되지 않음) :

    또 다른 걸림돌은 Spring Boot와 @EnableAutoConfiguration을 사용하고 @EnableAspectJAutoProxy를 명시 적으로 켜고 Spring Bean의 AspectJ 직조를 해제하는 것이다. 실제로 이것이 @EnableAspectJAutoProxy의 의도 된 부작용인지 잘 모릅니다.하지만 자동 구성에서 제외하여 비활성화 할 수 있습니다.

    @ComponentScan
    @EnableAutoConfiguration(exclude=AopAutoConfiguration.class)
    public class Application {    
        ...
    }
    

    N.B. Spring이 당신을 위해 프록시를 생성 할 것이기 때문에 당신이이 구성을 제외하는 것을 잊었을 때 직조가 꺼져 있다는 것을 알아 채지 못할 것입니다.

  2. ==============================

    2.여기 내 구성은 다음과 같습니다.

    여기 내 구성은 다음과 같습니다.

    @Component
    @Aspect
    public class WebControllerAop {
        @Autowired
        private PersonService personService;
        //匹配com.zkn.learnspringboot.web.controller包及其子包下的所有类的所有方法
        @Pointcut("execution(* com.zkn.learnspringboot.web.controller..*.*(..))")
        public void executeService(){
    
        }
    }
    
    @RestController
    @EnableAutoConfiguration
    @ComponentScan
    public class FirstExample {
        public static void main(String[] args) {
            SpringApplication.run(FirstExample.class, args);
        }
    }
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>
    
    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-aop</artifactId>
      </dependency>
    

    그것은 잘 작동 할 수 있습니다.

  3. from https://stackoverflow.com/questions/21350966/using-autowired-with-aspectj-and-springboot by cc-by-sa and MIT license