Where should I instantiate my models in a ColdFusion Model Glue controller? - model-view-controller

Let's say I have a client who has a list of orders and a wishlist. In my model, I have a ClientRepo, OrderRepo, and WishListRepo. In the controller, where should I be instantiating these repositories? Is it a good idea to make them class-level instances?
component ClientController
{
ClientRepo = new ClientRepo();
OrderRepo = new OrderRepo();
WishListRepo = new WishListRepo();
public void function HomePage(any event)
{
var clientId = event.getValue("id");
var client = ClientRepo.getClientById(clientId);
var orders = OrderRepo.getOrdersForClientId(clientId);
// put the variables into the event object for the view to access
}
}
Or would a better design be to instantiate them within the function?
public void function HomePage(any event)
{
var ClientRepo = new ClientRepo();
var orderRepo = new OrderRepo();
var wishListRepo = new WishListRepo();
// rest of the code is the same
}
The assumption here is that other functions in ClientController need access to the same repositories.
Also, what is the lifetime of the controller? Is it once-per-request, once-per-session, or once-per-application?

Disclosure: I'm a contributor to the Model-Glue project so I probably know what I'm talking about :-)
CFML doesn't have true class-level instances like Java. If you want singletons (a single instance shared across many parts of an application) you need to either put it in a shared scope (yuk!) or use a bean container. Fortunately Model-Glue has tight integration with ColdSpring (a popular bean container for CFML), and Model-Glue 3 makes it easier than ever to use ColdSpring beans in your controllers.
First, edit your ColdSpring.xml to include definitions for your singletons:
<bean id="ClientRepo" class="MyApp.model.client.ClientRepo"/>
<bean id="OrderRepo" class="MyApp.model.order.OrderRepo"/>
This is only a simple example of course. ColdSpring is a powerful dependency injection framework based on Java's Spring. Check out the ColdSpring Quickstart for some of the other things you can do with it.
Once the beans are defined in ColdSpring, you could have your controller explicitly ask for them via getModelGlue().getBean() calls. However a better way is to declare your controller's dependency on those beans and let Model-Glue inject them into your controller for you. The dependency can be declared either in ModelGlue.xml or in your controller CFC. Here's how to declare bean dependencies in your controller:
component ClientController beans="ClientRepo,OrderRepo"
{
public void function HomePage(any event)
{
var clientId = event.getValue("id");
var client = beans.ClientRepo.getClientById(clientId);
var orders = beans.OrderRepo.getOrdersForClientId(clientId);
// put the variables into the event object for the view to access
}
}
Any declared beans are injected into the "beans" scope of your controller by the framework so they're ready to use by any listener functions. Note however that bean injection occurs after initialization, so you cannot use them an init() function.
ColdSpring beans are singletons by default, so if the same ColdSpring bean is injected into multiple controllers they will all end up with the same instance of the bean. If you add singleton="false" to the bean definition then each controller will each end up with a different instance; I can't think of why you would want to do that though.
For more information on bean injection in Model-Glue, check out the Bean Injection HOWTO on the Model-Glue Wiki.
Model-Glue 3.1 instantiates all its controllers at framework initialization time as singletons, so each controller is created once-per-application. Future versions may delay the instantiating of controllers until they are first needed, so it's best to not make assumptions on when they are initialized. If you really need to have some code in a controller executed on application initialization time, I suggest you add an onApplicationStart listener to it.

Related

Creating Spring beans dynamically runtime using method

I have to use company's custom made libraries with Spring Boot and wondering if I'm able to create bean like this in runtime and add it to Spring application context.
#Bean(name = {"customConnectionFactory"})
public ConnFactory connector() {
return new SimpleConnFactory(configuration(), "prefix");
}
So this worked fine when I was allowed to wire beans normally when starting the application. Now requirements have changed and I should be able to do this dynamically runtime. I've done some research and it seems that it's possible to add class to spring context runtime, but how about running method which returns new object?
Could be something like this
DefaultListableBeanFactory beanFactory = //get and store the factory somewhere
MyBean newBean = new MyBean();
beanFactory.initializeBean(newBean,"TheBeanName"); //could be class' canonical name
beanFactory.autowireBeanProperties(newBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
beanFactory.registerSingleton("TheBeanName", newBean);

Spring prototype following prototype design pattern

Spring provides bean scope as "Prototype". Means whenever bean is required in application, Spring container will create a fresh/new instance of bean.
Does is follow prototype design pattern also?
Does it create object only once and in subsequent request calls clone() method on created object to create new object?
Also if someone can provide example of prototype in JDK, Spring, Hibernate or any J2EE framework.
No spring does not use cloning to create prototype scoped instances.
Below is the code snippet taken from AbstractBeanFactory.doGetBean() function:
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
#Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
The createBean method call boils down to below code:
BeanUtils.instantiateClass(constructorToUse);
Spring does not use the Prototype Pattern, it uses reflection.
Plus, in order to use clone() it would have to subclass somehow a bean, because clone() is protected, so it does not use clone() either.
Here is a code fragment from
org.springframework.beans.factory.support.SimpleInstantiationStrategy
where you can see the use of java.lang.reflect.Constructor and java.lang.Class reflection method:
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
if (beanDefinition.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (beanDefinition.constructorArgumentLock) {
constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
...
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
...
}
...
}
...
}
So the term prototype is used to suggest that at every call to getBean, you'll get a new instance with the same properties. This is more than a simple call to a constructor however, because you'll get a bean with all dependencies wired and other properties set, so in a sense it is a prototype. Or at least it fits the concept very well.
I have not dug into Spring source code, but I think Beans with prototype scope in Spring are not created using clone() method because it is not mandatory to implement the Cloneable interface for those beans.
Moreover, suppose it is creating them using clone(). It would then be dangerous if someone is expecting deep copy instead of shallow copy.
You can always test it and find the answer.
No. Spring scopes such as prototype or singletone do not follow strictly design patterns. The naming of scopes was used to intuitively suggest behavior container provides.
This way you can have a "singleton" pattern within the container and create another object outside of the container. Similarly "prototype" pattern does not have to implement "clone" functionality.
You may want to look into this link as well: Singleton design pattern vs Singleton beans in Spring container
More elaborate explanations here:
https://springframework.guru/gang-of-four-design-patterns/prototype-pattern/

Injection using NInject in ISiteMapNodeVisibilityProvider

I have a small problem which, hopefully, you will help me put behind.
I am using a MvcSiteMapProvider, and I want to define visibility for each node using access to a DB via a service interface.
public class AreaSiteMapNodeVisibilityProvider : MvcSiteMapProvider.Extensibility.ISiteMapNodeVisibilityProvider
{
[Inject]
public ISecurityService _SecurityService {get;set;}
public AreaSiteMapNodeVisibilityProvider()
{
}
public bool IsVisible(SiteMapNode node, HttpContext context, IDictionary<string, object> sourceMetadata)
{
MvcSiteMapNode thisNode = node as MvcSiteMapNode;
return _SecurityService.CalculateNodeVisibility(thisNode,context.Cache["someValueIHaveStoredHere"])
}
}
However, my _SecurityService member is always null. Any suggestions? I accept any type of directions, including getting rid of my injection and going another way.
Your ISecurityService is null, because in this case, Ninject is not managing the creation of MvcSiteMapProvider (in MVC app, Ninject resolves dependencies wired from controller root, because it manages the creation of controllers - it overrides the default method for creation controllers).
Options to resolve your issue:
1)
Use Ninject as service locator. Not recommended!, as it is widely considered to be an anti-pattern (but it depends...).
var app = HttpContext.ApplicationInstance as NinjectHttpApplication;
var service = app.Kernel.Get<ISecurityService>();
2) Read R. Gloor's answer on similar question: MVC3, Ninject, MvcSiteMapProvider - How to inject dependency to overridden method and do it his way.
Make sure that
The siteMapNodeVisibilityProvider is NOT configured in the web.config
There is a binding for ISiteMapNodeVisibilityProvider

Spring configuration calling more than one method

I have code which looks like the following:
MyContext context = new MyContext();
context.start();
MyEntity entity = context.getEntity();
I want to inject the MyEntity instance into various classes.
But I don't know how to setup my Spring configuration, where I first create an object, then call a method on it and then finally call another method which returns the entity I want to inject.
EDIT 2 - removed the Strings altogether
The most common type of dependencies injected using Spring don't depend on the user input for their construction. This includes data access objects, services etc.,
You are talking about injecting domain objects whose construction depends on the user input either directly or indirectly.
Spring provides #Configurable annotation to inject such domain objects that are created using new operator. You can search for "#Configurable Domain Driven Design" on the internet to get examples of how this can be implemented. I myself used it in one my applications and wrote a simple post here that might help you get started.
Edit:
To create a bean of type MyEntity as per the specification in your updated question, you would need to
define a bean of type MyContext
Create a MyEntityFactory class that would depend on the MyContext bean.
The factory method would take the MyContext bean as argument, calls context.start() on it and returns an instance of MyEntity.
You would define the MyEntity bean using this factory class.
The MyEntityFactory class would be as follows:
public class MyEntityFactory
{
public static MyEntity getMyEntity(MyContext context)
{
context.start();
return context.getEntity();
}
}
The spring bean configuration will be as follows:
<bean id="myContext" class="FQCN.Of.MyContext" />
<bean id="myEntity" class="FQCN.Of.MyEntityFactory" factory-method="getMyEntity">
<constructor-arg ref="myContext" />
</bean>
Since MyEntity is a singleton bean, the factory method will be called only once, btw.
More on creating beans using factory methods here.

How to 'get' the spring prototype beans cleanly?

I would like my other classes to interact with my domain's interfaces rather than implementation, and i would like to avoid hardcoding the implementation in the code, such as this example :
public void addToMyList(String s, int i) {
DomainModel model = new DefaultDomainModelImpl(); // it's hardcoding the implementation here
model.setName(s).setAge(i);
myList.add(model);
}
If i use spring container, with the prototype scope, i can use something like :
// <bean id="myDomainBean" scope="prototype" class="my.package.domain.MyDomainImpl" />
DomainModel myDomainModel = springContext.getBean("myDomainBean");
But i would like to avoid accessing springContext explicitly in my code.
I wonder what's the clean way to do this ?
Im currently thinking of creating a factory implementation for each domain implementation, and autowire the factory to create the beans, but that means different implementations of my domain will have different implementations of the factory also.
Please share your opinions, thank you !
Im currently thinking of creating a factory implementation for each domain implementation, and autowire the factory to create the beans, but that means different implementations of my domain will have different implementations of the factory also.
That is not 100% correct. You can have a factory that take the Interface (class) of the Domain objects that needs to be create. You can inject that factory in you class.
So you will get all the requriements you asked for:
no hard coded new
the domain object code has no dependence to spring
you only have one factory class and one factory method.
example
#Inject
MyStrangeSpringHiddingFactory myStrangeSpringHiddingFactory;
DomainModel myDomainModel = this.myStrangeSpringHiddingFactory.
createInstanceOf(DomainModel.class);
class MyStrangeSpringHiddingFactory implements MyStrangeSpringHiddingFactory {
#Inject
ApplicationContext springContext:
public <T> createInstanceOf(Class<T> clazz) {
return springContext.getBean(clazz);
}
}
This are only my thoughts, because I do not know your use case: Do you really need such in abstraction? Do you really have a domain model where a domain class have several subclasses that need a factory.

Resources