2015-10-31 3 views
4

Я пытаюсь реализовать одно из предложений, данное нашим элементом stackoverflow здесь Logging entry, exit and exceptions for methods in java using aspects. Поскольку это другой вопрос сам по себе, размещая здесь снова.nullpointer exception in aspectJ пример

Я попытался выполнить поиск, но, похоже, разные версии имеют разные способы сделать это и не могут найти пример в Интернете. Я пробовал следующий простой пример, так как я новичок в аспектно-ориентированном программировании и не мог понять, как реализовать. Этот пример бросает NPE. Пожалуйста, помогите мне понять, где я делаю это неправильно.

==== Исключение

Exception in thread "main" java.lang.NullPointerException 
at aoplogging.SimpleCall.call(SimpleCall.java:13) 
at aoplogging.App.main(App.java:18) 

Ровно в SimpleService.simpleCall();

ApplicationContext:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:task="http://www.springframework.org/schema/task" 
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> 


<aop:aspectj-autoproxy /> 
<bean id="simpleCall" class="aoplogging.SimpleCall" /> 

============== ==== App.java

package aoplogging; 

import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class App { 


public static void main(String[] args) { 
    ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); 
    SimpleCall call =(SimpleCall) context.getBean("simpleCall"); 
    call.call(); 
    context.close(); 
} 

============ SimpleCall.java упаковка aoplogging;

import org.springframework.beans.factory.annotation.Autowired; 

public class SimpleCall { 

@Autowired 
private SimpleService SimpleService; 

public void call(){ 


    SimpleService.simpleCall(); 
    try { 
     SimpleService.processingOperator(); 
    } catch (SMSProcessingException | SMSSystemException e) { 
     e.printStackTrace(); 
    } 
} 

}

===== Logging.java

package aoplogging; 

import org.aspectj.lang.annotation.After; 
import org.aspectj.lang.annotation.AfterReturning; 
import org.aspectj.lang.annotation.AfterThrowing; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 

@Aspect 
public class Logging { 
@Pointcut("execution(* aoplogging.*.*(..))") 
    private void selectAll(){} 

    /** 
    * This is the method which I would like to execute 
    * before a selected method execution. 
    */ 
    @Before("selectAll()") 
    public void beforeAdvice(){ 
     System.out.println("Going to setup student profile."); 
    } 

    /** 
    * This is the method which I would like to execute 
    * after a selected method execution. 
    */ 
    @After("selectAll()") 
    public void afterAdvice(){ 
     System.out.println("Student profile has been setup."); 
    } 

    /** 
    * This is the method which I would like to execute 
    * when any method returns. 
    */ 
    @AfterReturning(pointcut = "selectAll()", returning="retVal") 
    public void afterReturningAdvice(Object retVal){ 
     System.out.println("Returning:" + retVal.toString()); 
    } 

    /** 
    * This is the method which I would like to execute 
    * if there is an exception raised by any method. 
    */ 
    @AfterThrowing(pointcut = "selectAll()", throwing = "ex") 
    public void AfterThrowingAdvice(IllegalArgumentException ex){ 
     System.out.println("There has been an exception: " + ex.toString()); 
    } 

}

ответ

2

Я поддерживаю мое предложение;).

Использование Spring AOP/AspectJ является проблематичным при использовании компонентов, которые не вводятся с помощью интерфейса (с использованием интерфейса в точке впрыска), поскольку интерфейсы проксируются AspectJ.

Существует способ прийти вокруг этого путем добавления proxy-target-class="true" к

<aop:aspectj-autoproxy /> 

, но это не является хорошим способом.

Гораздо проще и безопаснее использовать интерфейсы.


EDIT: Еще одна ошибка в том, что вам не хватает компонента, реализующего SimpleService. Было бы проще добавить

<context:component-scan base-package="aoplogging" /> 

к вашему применениюContext.xml.

Затем вы должны пометить все бобы с

@Component 

для того, чтобы позволить Spring знать, что они бобы, что весна должна инстанцирование.


EDIT: Аспект должен быть аннотированный как с @Aspect и @Component для того, чтобы позволить Spring обнаружить.

+0

Какой интерфейс вы имеете в виду? SimpleCall call = (SimpleCall) context.getBean ("simpleCall"); – Atom

+1

Было бы лучше ввести интерфейс там. Но я обнаружил ошибку: у вас нет bean-компонента, который реализует SimpleService, поэтому он не может быть автоматически отпущен весной (обычно вы получаете excpetion ...). Было бы проще добавить в ваш applicationContext.xml. –

+0

Комментарий решает проблему. Благодарю. – Atom