Spring依赖注入带注释的Aspect

发布于 2024-08-03 02:51:34 字数 1377 浏览 15 评论 0原文

使用 Spring,我在对带注释的 Aspect 类进行依赖项注入时遇到了一些问题。 CacheService是在Spring上下文启动时注入的,但是当编织发生时,它说cacheService为空。所以我被迫手动重新查找 spring 上下文并从那里获取 bean。 还有其他方法吗?

这是我的方面的一个例子:

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;
  }
}

Using Spring I've had some issues with doing a dependency injection on an annotated Aspect class. CacheService is injected upon the Spring context's startup, but when the weaving takes place, it says that the cacheService is null. So I am forced to relook up the spring context manually and get the bean from there.
Is there another way of going about it?

Here is an example of my Aspect:

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;
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余厌 2024-08-10 02:51:34

由于切面是在 Spring 容器之前创建的,因此您必须从切面的工厂方法aspectOf(ExampleClass.class) 检索切面。

从 Spring XML 配置中,您可以像这样检索方面(对象):

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

工厂方法是检索在 Spring 容器外部创建的对象(如 Enum)的正常方法。

Since the aspect is created before the Spring container, you have to retrieve the aspect from the Aspect's factory method aspectOf(ExampleClass.class).

From the Spring XML configuration, you can retrieve the aspect (object) like this:

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

Factory methods are the normal way to retrieve objects created outside the Spring container like an Enum.

请你别敷衍 2024-08-10 02:51:34

据我了解,问题在于 Spring 正在为您创建这种类型的 bean,但 AspectJ 框架也在创建这种类型的实例化,因为它不知道 Spring 已经这样做了。

我相信您想为 Spring 提供一个工厂方法来实例化 bean,同时让 AspectJ 知道 Aspect 已创建:

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

为了给予应有的信任,我今天早些时候遇到了这个问题,然后找到了答案 其他地方 稍后,所以我会回来关闭循环。

我不太清楚这里发生的魔法,但我确实看到有一个 Aspects 类提供了一些这种风格的静态构造函数。据推测,AspectJ 也将同名的静态方法编织到每个 Aspect 上以促进这种构造。

The problem, as I understand it, is that Spring is creating a bean of this type for you, but the AspectJ framework is also creating an instantiation of this type because it doesn't know Spring has done so.

I believe you want to give Spring a factory-method to use to instantiate the bean that also lets AspectJ know the Aspect is created:

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

To give due credit, I came across this question earlier today and then found an answer elsewhere later, so I'm coming back to close the loop.

I'm not crystal clear on the magic happening here, but I do see that there is an Aspects class that provides some static constructors of this flavor. Presumably AspectJ is weaving static methods of the same name onto each Aspect as well to facilitate this kind of construction.

像极了他 2024-08-10 02:51:34

我也面临这样的问题。

这就是它的修复方式:

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

当然,不要忘记配置中的 以及方面 bean 定义。

I also faced with such problem.

This is how it was fixed:

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

And of course dont forget <aop:aspectj-autoproxy /> in your config along with aspect bean definition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文