Initiate and shutdown a instance in Spring Mvc - spring

I have following code
public enum MyInstances {
INSTANCE;
private InstanceClass instance;
private MyInstances(String param){initTitanGraph(param);}
private void initTitanGraph(String param){
instance = SomeFactoryClass.open(param);
}
public InstanceClass getInstance(){
return instance;
}
public void destroyInstance(){
//destroy or close all instances of InstanceClass class
}
}
Now I want to call
MyInstances.INSTANCE.getInstance();
to get the instance.
and
MyInstances.INSTANCE.destroyInstance();
to destroy instance.
I am using spring mvc. How can I implement the same class using spring mvc injection such that on application shutdown destroyInstance should be called and I can also use getinstance() to get instance anywhere.

there is no destroy method unless you define it. This doesn't do anything. The actual INSTANCE is still in memory whatever you do, as a singleton.
You are applying th esingleton pattern, just about, to an Enum.
Enums are hardwired by jvm to be singletons, without any extras from the programmer.
Application start and stop in spring can be achieved with #Postconstruct and #Predestory annotations.

Related

Spring - Injection of beans using Builder pattern

Context
An application that utilizes Spring 4.1.7. All configurations are in XML files (not using annotations) and I rather keep it that way (but I can change the ways things are done if I must).
Problem
I have created a new class that comes with a builder class.
Now I'd like to inject other beans into this new class. I can probably use lookup-methods and similar solutions to do that and then use the new class's builder in the caller beans to create an instance. However, I rather an instance of this new class to be injected to its caller beans then they creating one through the builder. This is where I'm not sure how I can do that. For example, this looks like an Abstract Factory to me, but I don't know how I can pass those parameters (which are passed to the builder) at runtime to the Abstract Factory and subsequently the factories it builds.
Some code snippets to make the question clearer:
public final class Processor {
private final StatusEnum newStatus;
private final Long timeOut;
// I'd like this to be be injected by Spring through its setter (below)
private DaoBean daoInstance;
private Processor() {
this.newStatus = null;
this.timeOut = null;
}
private Processor(Builder builder) {
this.newStatus = builder.getNewStatus();
this.timeOut = builder.getTimeOut();
}
// To be called by Spring
public void setDaoInstance(DaoBean instance) {
this.daoInstance = instance;
}
public void updateDatabase() {
daoInstance.update(newStatus, timeOut);
}
// Builder class
public static final class Builder {
private StatusEnum newStatus;
private Long timeOut;
// lots of other fields
public Long getTimeOut() {
return this.timeOut;
}
public StatusEnum getNewStatus() {
return this.newStatus;
}
public Builder withTimeOut(Long timeOut) {
this.timeOut = timeOut;
return this;
}
public Builder withNewStatus(StatusEnum newStatus) {
this.newStatus = newStatus;
return this;
}
public Processor build() {
return new Processor(this);
}
}
}
I'd like an instance of "DaoBean" to be injected to the "Processor" class. But to do that, Processor will have to be a bean or otherwise I have to utilize something like lookup-methods. On the other hand, wherever I want to use processor, I have to do something like this:
new Processor.Builder()
.withTimeOut(1000L)
.withNewStatus(StatusEnum.UPDATED)
.build()
.updateDatabase();
Instead of this, I wonder if I can make the Processor a bean that Spring can inject to its callers whilst maintaining its immutability. An instance of DaoBean can then be injected to the Processor by Spring. That way I'd be able to segregate the wiring code and the business logic.
It's worth mentioning that the Builder has a lot more than 2 fields and not all of them have to be set. This is why I thought an abstract factory is the way to go (building instances of the Processor in different ways).
One solution, while keeping the builder, would probably be to simply making the Builder itself a Spring bean...
This allows something like this..
#Autowired
private Builder builder;
public void someMethod() {
Result = builder.withX(...).doSomething();
}
This way, your Result object is immutable, can be created via a nice builder and the builder can inject the Spring bean (dao, in your case) into it without anyone even noticing that it's there.
And the only thing that changes is, that you don't create the builder yourself, but let Spring create it for you...
#Component
#Scope("prototype") // normally a good idea
public static class Builder {
#Autowired
private DaoBean dao;
// your logic here
}
(Same works with JavaConfig or XML config, if you don't want to scan.)
Especially with many combinations, I prefer a builder pattern, since a factory would need complex method signatures. Of course, the builder has the disadvantage that you cannot check at compile time if a given combination of attribute types is at least theoretically acceptable. Ok, you could simulate that with various builders, but that would probably be overkill.

What happens when autowired bean is initialized with new constructor?

I have used Spring in the past. I moved to a different team where I am getting familiarized with codebase. I found the following code and trying to understand how it works and how spring injects autowired objects in the case. From my basics of Spring, this is definitely not the right way to do. But surprisingly, this code is in production for a long time and no issues were identified.
#Controller
#RequestMapping("/start")
public class AController implements Runnable, InitializingBean {
#Autowired
private StartServiceImpl service = new StartServiceImpl(); // 1
Thread thread;
public void run() {
service.start();
}
public void stop() {
try {
thread.join();
} catch (InterruptedException e) {
}
}
}
#Override
public void afterPropertiesSet() throws Exception {
thread = new Thread(this);
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
}
}
#Component
public class StartServiceImpl {
//methods
}
Q1) What does localhost:8080/project/start is expected to do. There is NO GET or POST methods defined.
Q2) on the commented line 1, StartServiceImpl is both autowired and constructed with "new". So what happens here. Does the container inject bean or just an object is instantiated.
#Controller
#RequestMapping("/stop")
public class BController {
#Autowired
private StartServiceImpl service = new StartServiceImpl();
#RequestMapping(value = "**", method = RequestMethod.GET)
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
service.shutdownRequested();
new AController().stop(); // 2
} catch (Exception e) {
}
}
}
Q3) Again in commented line 2, does calling stop, calls the stop on the bean in the application context or a new object gets created and the stop method is called. What would happen in the latter case? Are we really stopping the service that was started or not? I think we are not stopping the service.
I have read this post. It is very useful. But it did not answer my question.
I will try to answer the questions specifically, as the purpose of the code is hard to understand (for me at least).
Q1) It is unclear for me what this code tries to achieve. As you noticed, it is not a controller, and I suspect that the only reason why it is registered this way is so that it gets auto-scanned (which might as well get done by using #Controller. This is just a hunch, I don't quite understand its purpose.
Q2) The answer is that two instances will be created, one via new, the other as a bean. When running in Spring, the final value of the field is the bean, because dependency injection happens after the construction. Typically this is done when the class is envisioned to be used outside Spring (e.g. a unit test), so that the field can be initialized with a default value.
Q3) stop() will be invoked on a new instance, and not the bean. The service bean is stopped because of the direct call above that line to the injected bean, but the next one will be an NPE, I guess, because afterPropertiesSet is not invoked on the target object created via new. the only reason why this doesn't show an NPE in the logs is because the exception is swallowed below. The thread variable is not initialized and remains NULL.
Hope this helps,
This code is flawed on many levels.
Ever since Java 5, manually starting threads is an antipattern. It's messy and way too low-level. ExecutorServices should be used.
A Rest controller that is a Runnable? That's a monstrous mingling of concerns.
A service is created via new but then overwritten with an autowired dependency? WTF!
etc.
I'd keep the thread running all the time, scheduling the task with the #Scheduled annotation and use the controller to toggle a flag that decides if the thread actually does somethin, e.g.
#Service
class StartService{
private boolean active;
public void setActive(boolean active){this.active=active;}
#Scheduled(fixedRate=5000)
public void doStuff(){
if(!active)return;
// do actual stuff here
}
}
And now all the rest controllers do is toggle the value of the "active" field. Benefits:
every class does one thing only
you always know how many threads you have
The code you posted is very strange.
Q1 ) What does localhost:8080/project/start is expected to do. There
is NO GET or POST methods defined.
I think localhost:8080/project/start will return 404 error (The requested resource is not available). Because there is no mapped methods in AController. #RequestMapping annotation on class level is not enough for make request to controller. There is have to be mapped method.
But service will be started anyway. Because AController implements InitializingBean. Method afterPropertiesSet() will be invoked by Spring after controller will be created and all fields will be initialized.
Q2) on the commented line 1, StartServiceImpl is both autowired and
constructed with "new". so what happens here. does the container
inject bean or just an object is instantiated.
Another strange snippet. Java will create new instance of StartServiceImpl on creation of instance of AController class. But after that, Spring will assign it's own instance(declared as component) to this field. And reference to firs instance (created by constructor) will be lost.
Q3) Again in commented line 2, does calling stop, calls the stop on
the bean in the appication context or a new object gets created and
the stop method is called. what would happen in the latter case? Are
we really stopping the service that was started or not? I think we are
not stopping the service
Actually service will be stopped. Because of invocation of service.shutdownRequested();. But thread in AController bean will continue to work. new AController().stop(); will invoke method of just created instance, but not method of controller (instance created by Spring).
This code is totally wrong usage of Spring framework.

Using Singleton enum in Spring MVC

Here is my singlton class using enum:
public enum MyInstanceFactory {
INSTANCE;
private SOMEOBJECT;
private int countInitialization = 0;
private MyInstanceFactory(){
countInitialization++;
System.out.println("WOW!! This has been initialized: ["+countInitialization+"] times");
SOMEOBJECT = SOMETHING
}
public Session getSomeobject(){ return SOMEOBJECT; }
}
Now I am calling it like inside MVC controller
Session cqlSession = MyInstanceFactory.INSTANCE.getSomeobject();
In this way it calls constructer only first time and next and onwards it return the correct value for SOMEOBJECT.
My question is I want to do the same thing when a spring application start i.e. initializing contructor once and use **getSomeobject** multiple times.
I saw THIS SO ANSWER but here they are saying
If it finds a constructor with the right arguments, regardless of visibility, it will use reflection to set its constructor to be accessible.
Will reflection create problem for a singlton class?
If you need a non-subvertible singleton class (not just a singleton bean that's shared by many other beans, but actually a singleton class where the class can only ever be instantiated once), then the enum approach is a good one. Spring won't try to instantiate the enum itself, because that really makes no sense; that would be a much more extremely broken thing to do than merely calling a private constructor.
In that case, to refer to the enum instance from Spring configuration, you do the same thing as for any other static constant; for example:
<util:constant static-field="MyInstanceFactory.INSTANCE" />

How to inject ISession into Repository correctly?

Please correct me on the following scenario. ( Question is at the end)
(I asked a similar question that was un-organized and it was voted to close. So I have summarized the question here into a scope that can be replied with exact answers.)
I am developing a web application with multiple layers using nhibernate as ORM. My layer structure is as follow
Model Layer
Repository Layer
Services Layer
UI Layer
with the above layers, the classes and interfaces are placed as below.
ProductController.cs (UI Layer)
public class ProductController : Controller
{
ProductServices _ProductServices;
NHibernate.ISession _Session;
public ProductController()
{
_Session = SessionManager.GetCurrentSession();
_ProductServices = new ProductServices(
new ProductRepository(), _Session);
}
// Cont..
}
ProductServices.cs (Service Layer)
public class ProductServices : IProductServices
{
protected IProductRepository _ProductRepository;
protected NHibernate.ISession _Session;
public ProductServices(IProductRepository productRepository,
NHibernate.ISession session)
{
_ProductRepository = productRepository;
_Session = session;
_ProductRepository.SetSession(_Session);
}
// cont...
}
ProductRepository.cs (Repository Layer)
public class ProductRepository : IProductRepository
{
NHibernate.ISession _Session;
public void SetSession(NHibernate.ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session.CreateCriteria<Product>().List<Product>();
}
//cont..
}
From the UI layer, I create the session as request per session and inject into service layer with the help of class constructor. Then set the session of repository with a help of a method.
I am afraid if I pass the _Session directly to repository as constructor, I will not have the control over it under the service layer. Also there is a future extension plan for using a webservice layer.
** Is there a way to ensure in each method of ProductRepository class that _Session is set already, without writing the piece of code if(_Session==null) in each and every method as it is repeating the same code.
** If the above pattern is wrong, Please show me a right way to achieve this goal.
What you are doing amazed me a bit. You applying the constructor injection pattern in the ProductService, which is definitely the way to go. On the other hand you are not injecting the dependencies into the ProductController, but that class is requesting one of those dependencies through a static class (this is the Service Locator anti-pattern) and creates a ProductServices class itself. This makes this class hard to test and makes your application less flexible and maintainable, since you can't easily change, decorate or intercept the use of the ProductServices class, when it's been used in multiple places.
And although you are (correctly) using constructor injection for the dependencies in the ProductServices, you are passing those dependencies on to the product repository, instead of applying the constructor injection pattern on the ProductResopistory as well.
Please show me a right way to achieve this goal.
The right way is to apply the constructor injection pattern everywhere. When you do this, your code will start to look like this:
public class ProductController : Controller
{
private ProductServices _ProductServices;
public ProductController(ProductServices services)
{
_ProductServices = services;
}
// Cont..
}
public class ProductServices : IProductServices
{
private IProductRepository _ProductRepository;
public ProductServices(
IProductRepository productRepository)
{
_ProductRepository = productRepository;
}
// cont...
}
public class ProductRepository : IProductRepository
{
private ISession _Session;
public ProductRepository (ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session
.CreateCriteria<Product>().List<Product>();
}
//cont..
}
See how each class only takes in dependencies that it uses itself. So the ProductController and ProductServices don't depend on ISession (I made the assumption that only ProductRepoistory needs ISession). See how -from a class's perspective- everything is much simpler now?
Did we actually solve a problem here? It seems like we just moved the problem of wiring all classes together up the dependency graph. Yes we did move the problem. And this is a good thing. Now each class can be tested in isolation, is easier to follow, and the application as a whole is more maintainable.
Somewhere in the application however, a ProductController must be created. This could look like this:
new ProductController(
new ProductServices(
new ProductRepository(
SessionManager.GetCurrentSession())));
In its normal configuration, ASP.NET MVC will create controller classes for you, and it needs a default constructor to do so. If you want to wire up controllers using constructor injection (which you should definitely do), you need to do something 'special' to get this to work.
ASP.NET MVC allows you to override the default ControllerFactory class. This allows you to decide how to create controller instances. However, when your application starts to grow, it will get really awkward very quickly when you are creating your dependency graphs by hand (as my last example shows). In this case, it would be much better to use a Dependency Injection framework. Most of them contain a feature / package that allows you to integrate it with ASP.NET MVC and automatically allows to use constructor injection on your MVC controllers.
Are we done yet? Well... are we ever? There's one thing in your design that triggered a flag in my brain. Your system contains a class named ProductServices. Although a wild guess, the name Services seems like you wrapped all product related business operations inside that class. Depending on the size of your system, the number of people on your team, and the amount of changes you need to make, this might get problematic. For instance, how to you effectively apply cross-cutting concerns (such as logging, validation, profiling, transaction management, fault tolerance improvements) in such way that to system stays maintainable?
So instead of wrapping all operations in a single ProductServices class, try giving each business transaction / use case its own class and apply the same (generic) interface to all those classes. This description might be a bit vague, but it is a great way to improve the maintainability of small and big systems. You can read more about that here.
You can use a dependency injection container such as Autofac to instantiate your session and manage the lifetime of it. Leave the responsibility of instantiating the session to Autofac and simply inject the ISession interface into any classes that require the dependency. Have a look at this post: Managing NHibernate ISession with Autofac
You will also find this wiki page useful about configuring Autofac with MVC3: http://code.google.com/p/autofac/wiki/MvcIntegration3

Windsor Castle IoC Thread Safety Static Variables

I have a question for the Ioc gurus out there.
I am working with a co-worker to wrap our minds around Castle Windsor IoC. We are having a difference of opinion about static Domain Service objects within asp.Net webforms. We have a static factory called BLServiceFactory in our Infrastructure layer that retrieves the container.
public sealed class BLServiceFactory
{
private static BLServiceFactory _instance = new BLServiceFactory();
IWindsorContainer _container = new WindsorContainer();
public static BLServiceFactory Instance
{
get
{return _instance;}
}
public T Create<T>()
{
return (T)_container[typeof(T)];
}
private BLServiceFactory()
{
_container.AddComponent("DataContext", typeof(DAL.DataContextFactory), typeof(DAL.CPContextFactory));
_container.AddComponent("Repository", typeof(DAL.IRepository<>), typeof(DAL.Repository<>));
_container.AddComponent("UserManager", typeof(BL.IUserManager), typeof(BL.UserManager));
_container.AddComponent("RoleService", typeof(BL.IRoleService), typeof(BL.RoleService));
}
}
We are pulling instances from the factory in our code behinds like this.
public partial class PrintList : System.Web.UI.Page
{
private static readonly ISchoolManager _schoolService = BLServiceFactory.Instance.Create<ISchoolManager>();
Models.TechSchool _tech;
protected void Page_Load(object sender, EventArgs e)
{
_tech = _schoolService.GetSchoolForTechPrep(Profile.UserName);
}
protected void DoOtherStuff...
{
_schoolService.Foo(_tech);
}
}
To me this looks like we will be serving up the same instance to every session. That would indeed be bad! My co-worker thinks that since all of our Domain Services are marked Transient, each page request will get a new instance.
I have also read a bit about memory leaks due to objects marked transient not released for garbage collection. Has this been addressed in the latest release of Castle Windsor, or should I be explicitly releasing objects? Of course as it stands now, all the objects are static and this would be irrelevant.
The BLServiceFactory is a service locator. I recommend using CommonServiceLocator instead of your own if you're going to use a service locator. Component registration does not belong inside the service locator.
Now, in the code you posted, there is no mention of those components being transient, unless you marked them with the [Transient] attribute. If you didn't, those components will be singletons, which is the default lifestyle in Windsor.
Since the variable _schoolService in PrintList is static, the same instance of ISchoolManager will be used for all requests to the PrintList page. If you really want it to be transient, remove the "static" keyword.
About releasing components, see this article.
BTW: AddComponent-style registration is deprecated, use Register() instead.

Resources