복붙노트

[SPRING] 스프링 의존성 주석이 달린 애스펙트 삽입하기

SPRING

스프링 의존성 주석이 달린 애스펙트 삽입하기

Spring 사용하기 주석이 달린 Aspect 클래스에 의존성 삽입을 할 때 몇 가지 문제가있다. CacheService는 Spring 컨텍스트가 시작될 때 삽입되지만, 위빙이 발생하면 cacheService가 null이라고 표시됩니다. 그래서 스프링 컨텍스트를 수동으로 다시 살펴보고 거기에서 콩을 가져와야합니다. 그것에 대해 갈 다른 방법이 있습니까?

다음은 내 측면의 예입니다.

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import com.mzgubin.application.cache.CacheService;

@Aspect
public class CachingAdvice {

  private static Logger log = Logger.getLogger(CachingAdvice.class);

  private CacheService cacheService;

  @Around("execution(public *com.mzgubin.application.callMethod(..)) &&"
            + "args(params)")
    public Object addCachingToCreateXMLFromSite(ProceedingJoinPoint pjp, InterestingParams params) throws Throwable {
    log.debug("Weaving a method call to see if we should return something from the cache or create it from scratch by letting control flow move on");

    Object result = null;
    if (getCacheService().objectExists(params))}{
      result = getCacheService().getObject(params);
    } else {
      result = pjp.proceed(pjp.getArgs());
      getCacheService().storeObject(params, result);
    }
    return result;
  }

  public CacheService getCacheService(){
    return cacheService;
  }

  public void setCacheService(CacheService cacheService){
    this.cacheService = cacheService;
  }
}

해결법

  1. ==============================

    1.애스펙트는 Spring 컨테이너보다 먼저 생성되기 때문에 Aspect의 팩토리 메소드 인 aspectOf (ExampleClass.class)에서 애스펙트를 가져와야한다.

    애스펙트는 Spring 컨테이너보다 먼저 생성되기 때문에 Aspect의 팩토리 메소드 인 aspectOf (ExampleClass.class)에서 애스펙트를 가져와야한다.

    Spring XML 설정에서 다음과 같이 애스펙트 (객체)를 검색 할 수있다.

    <bean id="traceAspect" class="aspects.trace.TraceAspect"
        factory-method="aspectOf" />
    

    팩토리 메소드는 Enum처럼 Spring 컨테이너 외부에서 생성 된 객체를 검색하는 일반적인 방법이다.

  2. ==============================

    2.문제는 내가 이해할 수 있듯이, Spring이이 유형의 bean을 생성하고 있지만, AspectJ 프레임 워크는 Spring이 그렇게하지 않았다는 것을 모르기 때문에이 유형의 인스턴스화를 생성한다.

    문제는 내가 이해할 수 있듯이, Spring이이 유형의 bean을 생성하고 있지만, AspectJ 프레임 워크는 Spring이 그렇게하지 않았다는 것을 모르기 때문에이 유형의 인스턴스화를 생성한다.

    AspectJ가 Aspect가 생성되었음을 알 수있는 bean을 인스턴스화하기 위해 Spring을 팩토리 메소드로 사용하기를 원한다고 생각합니다 :

    <!-- An @Aspect-annotated class -->
    <bean id="bar" class="com.foo.bar" factory-method="aspectOf">
        <property name="meaning" value="42" />
    </bean>
    

    정당한 신용을주기 위해, 나는이 질문을 오늘 일찍 만났고 나중에 다른 곳에서 답을 찾았습니다. 그래서 저는 그 고리를 닫으려고 돌아 왔습니다.

    나는 여기에서 일어나는 마법에 대해 명확하지 않지만,이 풍미의 정적 생성자를 제공하는 Aspects 클래스가 있음을 알 수있다. 아마 AspectJ는 이런 종류의 구조를 용이하게하기 위해 각 Aspect에 같은 이름의 정적 메소드를 짜 맞추고있을 것이다.

  3. ==============================

    3.나는 또한 그런 문제에 직면했다.

    나는 또한 그런 문제에 직면했다.

    이것이 수정 된 방법입니다.

    @Aspect
    public class MyAspect {
      @Resource // telling spring that at first look up bean by name;
      Session session; // resource that won't of being setup;
    
      private static class MyAspectHolder {
        static final MyAspect instance = new MyAspect();
      }
    
      ...
    
      // special purpose method w/o it - stuff doesnt work;
      public static MyAspect aspectOf() {
        return MyAspectHolder.instance;
      }
    }
    

    그리고 aspect bean 정의와 함께 설정에서 를 잊지 마십시오.

  4. from https://stackoverflow.com/questions/1343952/spring-dependency-injecting-an-annotated-aspect by cc-by-sa and MIT license