[SPRING] AspectJ와 Spring Boot에서 @Autowired 사용하기
SPRINGAspectJ와 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.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.여기 내 구성은 다음과 같습니다.
여기 내 구성은 다음과 같습니다.
@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>
그것은 잘 작동 할 수 있습니다.
from https://stackoverflow.com/questions/21350966/using-autowired-with-aspectj-and-springboot by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @Constructor annotation에 의해 annoted 된 Spring 구성 클래스에 기본 생성자가 있어야하는 이유는 무엇입니까? (0) | 2019.05.06 |
---|---|
[SPRING] 최대 절전 모드 : 클래스에 적절한 생성자를 찾을 수 없음 - HQL (0) | 2019.05.06 |
[SPRING] Spring Cloud AWS에서 Cloudform 사용 안 함 (0) | 2019.05.06 |
[SPRING] 스프링 보안으로 OAuth 2.0에서 resourceId의 의미 (0) | 2019.05.06 |
[SPRING] 스윙은 스프링 부트 아래에서 헤드리스라고 생각하지만 스프링이나 일반 자바에서는 그렇지 않다고 생각하는 이유는 무엇입니까? (0) | 2019.05.06 |