我想把@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
,但我出现了同样的错误。
如果我不使用aspect类,而是使用@controller
,我可以毫无问题地调用存储库。
一些文档谈到了spring的xml文件配置,但在spring boot,我没有这些文件。
这里是pom.xml的一部分,它调用aspectJ插件:
<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);
}
}
这里称为方面的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
。
下面是我的配置:
@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>
它可以很好地工作。
设置AspectJ编织是相当棘手的,所以这里可能会出现一些错误。我建议您不要在@aspect
上使用@component
(或者至少确保它从@componentscan
中排除)。这样做的原因是,您必须创建该类型的@bean
,并显式使用AspectJ所使用的相同创建机制,以便spring和AspectJ在单例实例的值上达成一致。我相信正确的方法是在@bean
定义中使用Aspects
中的静态便利方法。例如。
@Bean
public AspectSecurity interceptor() {
AspectSecurity aspect = Aspects.aspectOf(AspectSecurity.class);
// ... inject dependencies here if not using @Autowired
return aspect;
}
此外,您还需要aop.xml
来确保编译后的方面位于AspectJ weaver路径上。这可能就是您对Maven AspectJ插件所做的事情,但如果是我来做的话,我可能只需要手动创建一个aop.xml
,使用@enableLoadTimeWeaving
,然后放弃这个插件。你也许可以根据什么有效来决定你自己。
如果方面需要截取在构建应用程序上下文期间使用的东西,也可能存在生命周期问题。您也许可以通过不依赖@bean
方法中的任何拦截来避免这种情况,否则您就只能玩@dependson
的游戏,尝试强制执行特定的bean创建顺序。我还不能说你的应用程序是否会受到这种影响。
以前(与spring boot 1.3一起过时):
另一个绊脚石是,您使用的是spring boot和@enableautoconfiguration
,后者显式地打开@enableaspectjautoproxy
,并关闭spring bean方面的AspectJ编织。我实际上不知道这是否是@enableaspectjautoproxy
的预期副作用,但您可以通过将其从自动配置中排除来禁用它,例如。
@ComponentScan
@EnableAutoConfiguration(exclude=AopAutoConfiguration.class)
public class Application {
...
}
请注意。如果您忘记排除此配置,您可能不会注意到编织被关闭,因为spring将为您创建代理,您的许多方面无论如何都将正常工作。
7.7. 在Spring应用中使用AspectJ 到目前为止本章讨论的一直是纯Spring AOP。 在这一节里面我们将介绍如何使用AspectJ compiler/weaver来代替Spring AOP或者作为它的补充,因为有些时候Spring AOP单独提供的功能也许并不能满足你的需要。 Spring提供了一个小巧的AspectJ aspect library (你可以在程序发行版本中单独使用
使用的技术: Spring Boot 1.4.2.Release,Spring 4.3.4.Release,Tymeleaf 2.1.5.Release,Tomcat Embeded 8.5.6、Maven 3、Java 8 我创建了这个服务来发送电子邮件
希, 读了很多关于Spring AOP vs AspectJ的文章,我还是有些疑惑: 谢谢
我们的软件使用api(filenet p8),需要配置log4j。我们使用logBack和Spring Boot。我注意到,要在Spring Boot中使用log4j,我们必须排除logBack。这是不可能的。有没有办法在Spring Boot中并行运行log4j和logBack?谢啦
问题内容: 我试图找出一种将bean注入方面的方法。 我的意思是 作为使用Arquillian + Wildfly 8.2.1(托管和远程)的JUnit测试执行,我得到以下日志行: 我收到错误后不久 如果我做对了,它会抱怨Aspectjrt.jar不在类路径中,尽管我已经检查过并在依赖项中得到了它(使用Maven构建)。处于范围内,试图切换到但没有任何更改。 谁能帮我解决这个问题? 编辑:解决了最