如何在春季之前互相调用方法?

时间:2019-08-14 10:20:12

标签: java spring spring-boot

如何在春季之前互相调用一项服务中的方法?

我有一个服务,我通过注释@Service使它在spring之前进行管理, 但是我发现在此服务中,方法之间的相互调用不是由spring管理的,因此我在spring中使用的一些注释没有意义。

@Service
class Service {

    method a(){
        b(); // it's not invoked by spring, actually, it's invoked in a common way
    }

    method b(){
    }
}

使用SpringContextHolder.getBean(Service.class).b();是可行的。但是我想知道有一种更方便的方法吗?

非常感谢您。


更新

我发现有些困惑。最终可以自己注入。 当我在方法上使用自定义注释@LogTime时发现错误,导致注入组件为空!!!!!

例如:

 //  @LogTime
  public Response execute(Request request) {
    try {
      return okHttp.client.newCall(request).execute();
    } catch (IOException e) {
      log.error("OkHttp wrong", e);
      throw new SystemException("OkHttp wrong", e);
    }
  }

当我使用通过此方法创建的@LogTime注释时,client组件为null !!!!!!


最终更新

@Component
public class OkHttp {

  private final OkHttpClient client;
  private final OkHttp okHttp;

  public OkHttp(OkHttpClient client, @Lazy OkHttp okHttp) {
    this.client = client;
    this.okHttp = okHttp;
  }
}

总结:

可以注入自我,但不能使用okHttp.client.method()okHttp.clientnull 并且client不为空,可以将okHttp.client.method 直接替换为client.method()。 客户是由Spring管理的,因此我们可以实现相同的目标。

2 个答案:

答案 0 :(得分:2)

  

我发现在此服务中,方法相互调用不是由   春天

您需要了解Spring是通过代理来管理对象和对这些对象的方法的调用(有关更多详细信息,请参阅官方文档here。在本文档中,您将了解为何在其中使用方法调用的原因相同的类别不是“托管”)。这些代理的不同之处在于它们可以是Dynamic,CGlib或任何其他代理,具体取决于创建方式。您可以在脑海中想象一下,每当有spring托管类方法调用另一个spring托管不同类方法时,就会有一个代理。 但是,如果某个方法调用相同类的另一个方法,则它是没有代理的纯方法调用,因为没有机会拦截该调用并添加行为。

答案 1 :(得分:1)

常见方法是使用依赖项注入,例如与@Autowired

@Service
class MyService {

  @Autowired
  MyService thisService;  // inject a service itself

  public void a() {
    thisService.b();    // now, `b` will be called in a transaction
  }

  @Transactional
  public void b() {
    // ...
  } 

}

但是,这是一个糟糕的设计:这种bean不能在容器外部生活。