2014-01-25 5 views
9

Я хочу использовать @Autowired аннотацию в «Аспект». Я хочу добавить репозиторий в свой аспект, но когда я пытаюсь вызвать метод моего автоукрещенного класса, возникает NullPointException.Использование @Autowired с AspectJ и Springboot

@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()); 

    } 
} 

Я уже пытался добавить @Component выше моего аспекта класса, но у меня такая же ошибка.

Если я не использую класс аспект, а @Controller, я могу позвонить в свой репозиторий без проблем.

В некоторых документах рассказывается о конфигурации весны с файлами xml, но с загрузкой весны У меня нет этих файлов.

Вот часть моего pom.xml Wich звонка 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); 
    } 
} 

Здесь класс контроллера, который называется аспект:

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 выше моего класса приложения

спасибо за вашу помощь

+0

Где вы пытаетесь использовать Аспект? –

+0

Вы пытались добавить '@ Configurable' в класс аспект? – Pace

+0

Аспект используется после метода «create». Логического наименования нет. Это просто ПОС. В соответствии с выражением аспекта '@After (" выполнение (public * dash. *. * Controller. * (..)) ")' аспект вызывается для всех общедоступных методов, имеющих «Controller» в конце имени во всех классы всех пакетов пакета «dash» ^^ – maxiplay

ответ

14

Это довольно сложно настроить AspectJ ткачества так несколько вещей, которые можно было бы неправильно здесь. Я бы предположил, что вы делаете не используйте @Component на своем @Aspect (или, по крайней мере, убедитесь, что он исключен из @ComponentScan). Причина этого заключается в том, что вы должны создать @Bean этого типа и явно использовать тот же механизм создания, что и AspectJ, чтобы Spring и AspectJ соглашались на значение экземпляра singleton. Я считаю, что правильный способ сделать это - использовать статические методы удобства в Aspects в вашем определении @Bean. Например.

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

Кроме того, вы будете нуждаться в aop.xml, чтобы гарантировать, что скомпилированный аспект находится на пути ткацкого AspectJ. Возможно, это то, что вы делаете с плагином Maven AspectJ, но если бы я это делал, я бы, вероятно, просто создал aop.xml вручную, используйте @EnableLoadTimeWeaving и вытащите плагин. Вы, вероятно, можете сами решить, что работает.

Также могут возникать проблемы с жизненным циклом, если в аспекте необходимо перехватить что-то, что используется при конструировании контекста приложения. Вы можете избежать этого, не полагаясь на какой-либо перехват в методах @Bean, иначе вы в конечном итоге играете в игры с @DependsOn, чтобы попытаться заставить определенный порядок создания бина. Является ли ваше приложение страдать от этого, но я не могу сказать.

РАНЕЕ (устаревшее с весны Ботинок 1.3):

Другим камнем преткновения является то, что вы используете Spring бутсу и @EnableAutoConfiguration, которые явно переключается на @EnableAspectJAutoProxy, и выключает ткачество AspectJ для аспектов Spring боба. На самом деле я понятия не имею, является ли это предполагаемым побочным эффектом @EnableAspectJAutoProxy, но вы можете отключить его, исключив его из autoconfig, например.

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

N.B. вы не заметите, что плетение выключено, если вы забудете исключить эту конфигурацию, потому что Spring создаст прокси для вас, и многие ваши аспекты будут работать в любом случае.

+1

Вместо исключения AopAutoConfiguration вы также можете настроить: 'spring.aop.auto = false' – Ralph

-1

Вот моя конфигурация:

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

Он может хорошо работать.

Смежные вопросы