I have a question about #Service in spring, but i didn't find any response about it.
Situation :
I have a web application with #RestController using spring
Now for my service layer, I saw on some project two way of processing
#Service on service class and #Autowired on controller class (Create a bean that is a singleton excepted if we change the scope)
Create a object like a service
MyService service = new MySerivce()
So my questions are :
Create a object each time for each call of controller will not be a issue for memory ? If i create a load test (with Apache Jmeter) and send 1000 requests, it will create 1000 object my service so could be a problem no ?
Create a singleton with #Service will not be a issue for memory but, how spring will handle 1000 requests on 1 seconds for example. Will he push requests on a sort of queue and execute one at a time ?
What is the best practice for Service declaration and why ?
Thank in advance for any response
The whole point of dependency injection (using annotations such as #Autowired and #Service, #Component etc.) is to let Spring manage instances of service classes for you, instead of manually creating an instance with new MyService() each time you need it.
Letting Spring manage service class instances (and other Spring beans) has a number of advantages. For example, it makes it a lot easier to replace a service with a different implementation; you only need to change the Spring configuration for that. Also, it makes it easy to inject a mock version of a service for unit testing. Replacing real services with mocks would be really hard if the class you are trying to test is directly instantiating a specific implementation of the service class using new MyService().
how spring will handle 1000 requests on 1 seconds for example. Will he push requests on a sort of queue and execute one at a time ?
No. Calling a method on a service is just like any other method call. There is no invisible queue and there is also no reason why that would be necessary, as long as the methods in the service are thread-safe.
What is the best practice for Service declaration and why ?
When you use Spring, use Spring's dependency injection and never instantiate service classes using new in your code.
Spring Controller uses IOC mechanism like where Singleton objects are created, like in example you described #Service,
Application Server manages requests client, It uses thread pooling to handle request and generated or use same thread for request or response,
Spring applications are it self uses container mechanism where objects are created using #Service and #Autowired annotations.
When ever we are using #Service, this means we are telling spring
to create a object of that class and keep in Spring container, By
default its Singleton. Wherever we are using #Autowired then spring
handover that object to the Service/caller.
Whenever we are calling MyService service = new MySerivce()
java
creates new object of MyService every time. If that service called
1000 times then MyService object will get created 1000 times, and Spring
has no control on this.
Best Practice is :
Use Spring #Service annotation to create object and use annotation #Autowired to get that class object.
Handling 1000 Requests
Spring will not create 1000 new service object, it will use same service object (which is autowired) if object scope is Singleton which is default scope
but incase of Prototype, it is same as creating a object with new keyword.
SO in this case it will create 1000 objects.
For handling huge requests we need to make thread safe, pooling separately, in this case Spring will use its container pooling which is not very efficient.
Related
I want to define a annotation like #PlatformRelated, once it is marked in a interface, there will be a proxy bean at spring context, and this proxy bean should be #Priority.I want this proxy could invoke different implement according to key parameter #KeyPrameter.And I still wanna use spring features like #Async,#Trasaction,etc... at my Implement1 and Implement2.
#PlatformRelated
interface MyInterface {
method(#KeyPrameter String parameter);
}
#Component
class Implement1 implements MyInterface {
method(String parameter){
//do something 111
}
}
#Component
class Implement2 implements MyInterface {
method(String parameter){
//do something 222
}
}
#Service
class BusinessService{
#Autowired
private MyInterface myInterface;
public void doSomething() {
myInterface.method("key1");
//Implement1 work
myInterface.method("key2");
//Implement2 work
}
}
Do you guys have some good idea to complete it?
I must admit I haven't totally understood the meaning #Priority, however, I can say that if you want to implement this feature in spring, you should probably take a look at Bean Post Processors.
BeanPostProcessors are essentially a hook to Bean Creation process in spring intended for altering bean behavior.
Among other things, they allow wrapping the underlying bean into the proxy (CGLIB/java.lang.Proxy if you're working with interfaces, or even using programmatically Spring AOP), these proxies can provide a hook to the method execution that can read your annotations (like mentioned #KeyParameter) and execute a code in a way similar to Aspect's code that you already make use of.
Not all bean post processor wrap the bean into the proxy. For example, if you want to implement a BPP that uses "#Autowire", you will return the same bean, just "inject" (read, put by reflection) its dependencies. On the other hand, if you want to implement with BPP #Transactional behavior, then yes, you should wrap the bean into a proxy that would take care of transaction management capabilities before and after the method execution.
It's totally ok to have a spring bean that gets "altered" by many post processors, some of them would wrap it into a proxy other will just modify-and-return the same bean, If there are many BPP-s that wrap the bean into proxy we'll get "proxy inside proxy inside proxy" (you get the idea). Each layer of proxy will handle one specific behavior.
As an example, I suggest you take a look at existing Spring postprocessors, or, for instance, a source code of the following library: Spring Boot metering integration library
This library contains some implementations of post processors that allow metrics infrastructure integration by defining annotations on methods of Spring Beans.
Env:
Wildfly 8.2.0 Final
JDK 8
Java EE 7
Please note that by 'POJO' i am referring to the classes that serve the other classes i.e other than value objects, entities.
This question was on back of my head for some time. Just wanted to put it out.
Based on CDI and Managed Beans specs and various other books/articles, its pretty clear that CDI injection starts with a 'managed' bean instance. By 'managed' i mean servlet, EJBs etc. which are managed by a container. From there, it injects POJOs (kind of crawl through layers) till every bean gets its dependencies. This all makes very sense to me and i see very little reason why developers ever need to use "new" to create an instance of their dependent POJO's.
One scenario that comes to my mind is when developer would like to have logic similar to
if(something) {
use-heavy-weight-A-instance
} else {
use-heavy-weight-B-instance
}
But, that also can be achieved via #Produces.
Here is one scenario that i verified to be true in wildfly 8.2.0 Final i.e. CDI is not able to inject bean when the JSP has
<%!
#Inject
BeanIntf bean;
%>
But, the alternative to use a servlet works fine.
That said, would like to know if there is any scenario(s) where a developer has to use 'new'. As i understand, by using 'new', developer owns the responsibility of fulfilling dependencies into that bean and all its dependent beans, and their dependent beans etc..
Thanks in advance,
Rakesh
When using CDI or other container you don't use new, because you expect a bunch of service coming from the container.
For CDI these main services are:
Injection of dependent beans (get existing instance or create a new
instance)
Lifecycle callback management (#PostConstruct and
#PreDestroy)
Lifecycle management of your instance (a #RequestScoped bean will make container produce an instance leaving until the end of request)
Applying interceptors and decorators on your instance
Registering and managing observers methods
Registering and managing producers methods
Now, on some rare occasion, you may want to add a part of these services to a class you instantiate yourself (or that another framework like JPA instantiate for you).
BeanManager bm = CDI.current().getBeanManager();
AnnotatedType<MyClass> type = bm.createAnnotatedType(MyClass.class);
InjectionTarget<MyClass> it = bm.getInjectionTargetFactory(type).createInjectionTarget(null);
CreationalContext<MyClass> ctx = bm.createCreationalContext(null);
MyClass pojo = new MyClass();
injectionTarget.inject(instance, ctx); // will try to satisfied injection points
injectionTarget.postConstruct(instance); // will call #PostConstruct
With this code you can instantiate your own MyClass containing injection points (#Inject) and lifecycle callbacks (#PostConstruct) and having these two services honored by the container.
This feature is used by 3rd party frameworks needing a basic integration with CDI.
The Unmanaged class handle this for you, but still prevent you to do the instantiation ;).
I have a java file "DatabaseMan.java" that helps connect to a database and connects helper functions. How can I make it such that it is created once for the life of my spring application, and I can call of its methods "getAllRows" for example, in each of my other resource classes?
Should I be declaring a bean in my Application.java or using some sort of annotation on my "DatabaseMan" class to indicate that it is "injectable"/"resusable"?
I see the following Spring3 example:
http://www.mkyong.com/spring3/spring-3-javaconfig-example/
The issue is, do I have to include this within every single resource:
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
HelloWorld obj = (HelloWorld) context.getBean("helloBean");
obj.printHelloWorld("Spring3 Java Config");
Is there a better way to get to the "HelloWorld" with less code and more annotation in Spring 4?
Remember, the ApplicationContext is a container to manage all your beans and their inter-dependencies. It is the entry point to your application. Once you've set it up, all the managed objects are linked up and ready to go.
Is there a better way to get to the "HelloWorld" with less code and more annotation in Spring 4?
It depends where you want to get it. If you want to get it from outside the ApplicationContext, then you need to do what you did. If you want to get into another bean, just inject it and the ApplicationContext will do the rest.
#Component
class SomeOtherBean {
#Autowired
private HelloWorld helloWorldBean;
// do something with it
}
Writing a small web-app in Grails I encountered a problem with global objects. I have a class which runs threads - ExecutorService with queuing.
The problem is where to create an object of this class, to have it available in Controller?
I've tried at init (BootStrap) but there's no chance then of getting its instance anywhere else.
In general - what I need is an object in one single instance for whole application, with access from Model and/or Controller.
In general - what I need is an object in one single instance for whole application, with access from Model and/or Controller.
The standard way to achieve this is to declare the object as a Spring bean in grails-app/conf/spring/resources.groovy
threadPool(java.util.concurrent.Executors) { bean ->
bean.factoryMethod = "newCachedThreadPool"
}
Then in controllers/services/etc. you can inject this bean the same as you would with grails services, i.e.
def threadPool
But in this case you may find it easier simply to use the executor plugin, which defines such a bean for you and handles the intricacies of ensuring there is a valid GORM session available to the background tasks.
Why not wrap your Executorservice inside a Spring Bean, or using something like:
grailsApplication.controllerClasses.each {controller ->
controller.metaClass.executorService = { ->
executorService
}
}
Actually I have come to something before checking answers.
For a given domain class (Example) and controller (ExampleController) create
ExampleService
and simply include all the needed things there. Set behaviour to #Singleton (default).
Then in Controller inject the instance as follows:
def exampleService
I wrote a custom Struts RequsetProcessor for my application that is manually fetching some references from Spring. It is working just fine, but I would like to do the "right" thing and inject everything I need at construction time.
Is there a way to define a custom Struts RequestProcessor in a way that I can inject Spring objects into it when Struts instantiates this RequestProcessor?
The short answer is "NO". The long answer is "kind of":
Assuming Struts is integrated with Spring in your application via ContextLoaderPlugin, you can do one of two things:
A) Create a "ProcessorContext" bean (or whatever you want to call it) that you would define in your Spring context and access from your custom request processor by obtaining it from Spring's context (which you can get via WebApplicationContextUtils.getWebApplicationContext(getServletContext())).
B) If your custom processor extends Spring's DelegatingRequestProcessor or DelegatingTilesRequestProcessor you can instead write a new request processor that would do what you want functionality-wise, bind it to Spring context with all your dependencies and then extend DelegatingRequestProcessor or DelegatingTilesRequestProcessor to get it from context (either via type or id) and delegate to it. This is essentially an extension of (A) but it delegates all Spring's plumbing to Spring's request processor extension leaving your custom processor Spring-independent.
Spring / Struts integration is described in detail here.