Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Produce prototype objects from singleton? (Design help needed)

I'm relatively new to Spring and I've got myself dug in a hole. I'm trying to model motor cars. Each model has it's own builder object, and I have a BuilderFactory that returns the correct builder based upon user selection from a web-app.

So I'm looking for suggestions on how to approach this problem where I need to create a number of individual vehicles, but I don't know what type of vehicle I'm going to need until run-time, and each vehicle needs to be unique to the user.

What I've got at the moment is shown below. The problem I have at the moment is that because the individual builders are singletons so are the individual vehicles. I need them to be prototypes. I know it all looks pretty horrible so I'm sure there must be a better way of doing this.

The top level from the web-app looks like;

Vehicle vehicle = vehicleBuilderFactory.getBuilder(platform).build();

My vehicleBuilderFactory looks like this;

@Service
public class VehicleBuilderFactory {

@Autowired
Discovery3Builder discovery3Builder;
@Autowired
Discovery4Builder discovery4Builder;

    // Lots of @Autowired statements here. 

@Autowired
FreeLander2010Builder freeLander2010Builder;



public VehicleBuilder getBuilder(Platform platform) {

    switch (platform.getId()) {

    case 1: return discovery3Builder;
    case 2: return discovery4Builder;

            // Lots of case statements here

            case 44: return freeLander2010Builder;
    default: return null;
    }
}

}

which itself looks pretty horrible. Each individual builder looks like;

@Service
public class DefenderBuilder implements VehicleBuilder {

@Autowired
Defender defender;

// Loads of Defender specific setters ommitted  
@Override
public Vehicle build() {
    return defender;
}

}

and finally the individual vehicle

@Service
@Scope("prototype")
public class Defender extends Vehicle {

}

The main problem now, is that because the builders are singletons, so are the vehicles, and I need them to be prototypes, because User A's Defender is different to user B's Defender.

like image 985
user497087 Avatar asked May 26 '11 09:05

user497087


People also ask

Can we create prototype bean in singleton bean?

When you work with a prototype bean in a singleton, you have three options to get a new instance of the prototype: Spring can autowire a single prototype instance when it creates the singleton. It's the default framework behavior. Spring can create a new prototype instance on every call to any method of this prototype.

Can we inject a singleton bean into a prototype bean?

When you use singleton-scoped beans with dependencies on prototype beans , be aware that dependencies are resolved at instantiation time. Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean.

In which scenario you will use singleton and prototype scope?

As a rule of thumb, you should use the prototype scope for all beans that are stateful, while the singleton scope should be used for stateless beans.

Where do you use Singleton pattern in your project?

Singleton pattern is used for logging, drivers objects, caching and thread pool. Singleton design pattern is also used in other design patterns like Abstract Factory, Builder, Prototype, Facade etc. Singleton design pattern is used in core java classes also, for example java.


1 Answers

You can use Spring's ObjectFactory to have it service up prototype scoped beans from a singleton scoped bean. The usage is pretty straightforward:

@Component
class DefenderBuilder implement VechicleBuilder {

  @Autowired
  ObjectFactory<Defender> defenderFactory;

  Defender build() {
     return defenderFactory.getObject()
  }
}

@Component
@Scope("prototype")
class Defender {

}

This returns a new Defender on each call to defenderFactory.getObject()

like image 191
Fil Avatar answered Sep 28 '22 03:09

Fil