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.
Related
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.
Which is the best approach to implement several different databases in one project, using Spring JdbcDaoSupport?
I have several DB with different datasources and syntax: MySQL & Postgres, for example. In pure java-jdbc projects i used Factory Method and Abstract Factory patterns, and multiple DAOimpl classes (one for each DB) with common DAO interfaces for switch between databases. Now i use Spring-jdbc and want to implement similar behavior.
I faced the same matter two year ago and I finally choose an implementation based on a "Spring Custom Scope" (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-scopes-custom).
The spring frameworks allows multiple instances of the same bean definition to coexists together. They differ only from some contextual settings.
For instance, this bean definition will create various loginAction bean depending on the currently processed HTTP request
<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>
If you create a custom scope called "domain", you will be able to instanciate several datasource based on the same bean definition.
A datasource bean definition based on JndiObjectFactoryBean would let the servlet container manage the database connection (through the web.xml file). However, you would have to variabilize your datasource name with a Spring Property.
Beans like the database Transaction Manager must also be marked with this scope.
Next you need to activate the scope each time an HTTP request is running: I can suggest you to define the datasource name as a prefix of the request url.
Because most of web frameworks allows you to intercept HTTP requests, you can retrieve the expected datasource before processing the request.
Then, create (or reuse) a set of beans specific to the selected datasource and store it inside a ThreadLocal variable (that your custom scope implementation will rely on)
This implementation should look a little complex at first glance, but its usage appears transparent.
I am new to Spring and have a project where I am trying to inject something like the following beans:
ProductHandle selectedProduct
List<ProductHandle > allProducts
When I try to have a List<ProductHandle> autowired into another class, it injects a List containing selectedProduct, rather than the list I actually want. This is even though the name of the autowired property is called allProducts, so I thought this would identify the correct bean.
How would I go about achieving what I want?
--
Edited to show that it isn't just a case with Strings - this is a more generic and hopefully less offensive case..
--
Note beans are being registered as so, since the values are being parsed from command line args.
mySelectedProduct is a ProductHandle
allMyProducts is a List<ProductHandle>
try (final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext()) {
ctx.registerBeanDefinition("selectedProducts", BeanDefinitionBuilder
.rootBeanDefinition(ProductHandle.class, "create")
.addConstructorArgValue(mySelectedProduct)
.getBeanDefinition());
ctx.registerBeanDefinition("allProducts", BeanDefinitionBuilder
.rootBeanDefinition(Lists.class, "asList")
.addConstructorArgValue(allMyProducts)
.getBeanDefinition());
ctx.refresh();
final MyApp app = ctx.getBean(MyApp.class);
app.run();
}
Using standard data structures as Spring beans is an antipattern, don't do it. (Read here about "stringly typed" software)
Either inject the list as a #Value, or wrap it in a custom object that expresses the intent.
Regarding your updated question:
If you have a bean of type X, and register a dependency of type List<X>, Spring will inject a list of all dependencies of the supplied type.
While this is a very handy feature, it's also one more reason never to define standard data structures (like Lists) as Spring Bean. Wrap your list in a custom object and you should be fine.
Also: ProductHandle sounds like it's a business object. Usually, you should not let Spring manage these, but rather the services that act on business objects. Typically, Spring would know about a ProductRepository, or a ProductService, but not a Product or ProductHandle.
The web layer is a notable exception to this rule, but even there, business objects should be method parameters, not 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'd like to test my gwt client using the gwt-test-utils library (http://code.google.com/p/gwt-test-utils/). While the standard implementation already delivers a GwtCreateHandler (used to mimic GWT.create on RemoteService) that handles / mappings, it does nothing to handle the Guice servlet extension (GuiceFilter / GuiceServletContextListener).
Basically I need to find the servlet, or the servlet class that handles a specific url, that I know:
String url = ... // I know this.
// I know everything else (Injector, GuiceServletContextListener, etc).
Class<?> servletClazz = ... // How to get this?
Is this even possible?
Of course, running a GWTTestCase would work, but:
it is too slow
gwt-test-utils is pure java, so I don't see why it would not be possible
Thanks,
Alex D.
Checkout Tadedon:
Bind application configuration in Guice module.
Support #PostConstruct and #PreDestroy annotations (JSR 250) in
Guice application. incject slf4j loggers.
annotate your methods with #Transactional annotation.
Support guice stage in your web application.
test your guice managed servlets and filters without need of real
servlet container.
use guice Matchers for matching super class, interface and type
literal annotations