当前位置: 首页 > 知识库问答 >
问题:

在AspectJ和springboot中使用@AutoWired

阴永福
2023-03-14

我想把@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

共有2个答案

公羊浩气
2023-03-14

下面是我的配置:

@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>

它可以很好地工作。

丌官玺
2023-03-14

设置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构建)。处于范围内,试图切换到但没有任何更改。 谁能帮我解决这个问题? 编辑:解决了最