Reputation: 329
How can I do to invoke methods in one service each other by spring?
I have one Service, I make it manage by spring by annotation @Service, but I found In this service, methods invoke each other is not manage by spring, So some annotation in spring I use makes no sense.
@Service
class Service {
method a(){
b(); // it's not invoked by spring, actually, it's invoked in a common way
}
method b(){
}
}
It's work by using SpringContextHolder.getBean(Service.class).b();
.But I wanna to know there is a more convenient way ?
Thank you very much.
I found something confused. It's ok to inject itself eventually.
And I found something wrong when I use my custom annotation @LogTime
over a method, which results in the inject component is null !!!!!
for example:
// @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);
}
}
When I use @LogTime
annotation I created over this method, the client
component is 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;
}
}
It's ok to inject self, but it's not ok to use okHttp.client.method()
.
the okHttp.client
is null
and client
is not null, It's ok to replace okHttp.client.method
with client.method()
directly.
the client is managed by spring, so we can achieve the same goal.
Upvotes: 3
Views: 2169
Reputation: 14348
The common way is to use dependency injection, e.g. with @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() {
// ...
}
}
Though, this is a poor design: such bean cannot live outside a container.
Upvotes: 1
Reputation: 9102
I found In this service, methods invoke each other is not manage by spring
You need to understand that Spring manages objects and calls made to methods of those objects via proxies ( read official documentation here for more details. In this documentation you will get to know the reason why method to method calls within same class is not "managed" ). These proxies can differ in that they can be Dynamic, CGlib or any other depending on how they are created. You can mentally imagine a proxy in between whenever there is spring managed class method calling another spring managed different class method. However in case of a method calling another method of same class it's pure method call without proxy because there is no opportunity to intercept the call and add behavior.
Upvotes: 2