What is BeanFactory?
The BeanFactory is the actual container which instantiates, configures, and manages a number of beans.Let have a look at how spring works

How it Works

  1. When the application is Deployed the Spring framework reads the xml file and creates the objects.Those are the objects which you see in the Spring Container
  2. Now when you try to refer any of these objects from the outside object using the new method it will throw an exception since or when you try to create a object using new method, the spring container has no idea about the object which you are trying to access
  3. Now to access the object in the container you will use the BeanFactory Objects

BeanFactory is represented by org.springframework.beans.factory.BeanFactory interface.It is the main and the basic way to access the Spring container.Other ways to access the spring container such as ApplicationContext,ListableBeanFactory, ConfigurableBeanFactory etc. are built upon this BeanFactory interface.

BeanFactory interface defines basic functionality for the Spring Container like

  1. It is built upon Factory Design Pattern
  2. provides DI / IOC mechanism for the Spring.
  3. It loads the beans definitions and their property descriptions from some configuration source (for example, from XML configuration file) .
  4. Instantiates the beans when they are requested like beanfactory_obj.getBean(“beanId”).
  5. Wire dependencies and properties for the beans according to their configuration defined in configuration source while instantiating the beans.
  6. Manage the bean life cycle by bean lifecycle interfaces and calling initialization and destruction methods.

Note that BeanFactory does not create the objects of beans immediately when it loads the configuration for beans from configuration source.Only bean definitions and their property descriptions are loaded. Beans themselves are instantiated and their properties are set only when they are requested such as by getBean() method.

Different BeanFactory Implementations:

XmlBeanFactory using Constructor:

Resource res = new FileSystemResource("c:/beansconfig.xml");
BeanFactory bfObj = new XmlBeanFactory(res);
MyBean beanObj= (MyBean) bfObj.getBean("mybean");
  1. The XmlBeanFactory takes the resource object as Parameter
  2. bfObj points to the Spring Container from which you try to fetch the object
  3. mybean is the ID of the Object specified in the XML File
  4. In the above case BeanFactory loads the beans lazily.BeanFactory will read bean definition of a bean with id “mybean” from beansconfig.xml file, instantiates it and return a reference to that.
  5. There are tow implementation of Resource Intefrace. one is org.springframework.core.io.FileSystemResource as seen above and other is org.springframework.core.io.ClassPathResource which loads Loads the resource from classpath(shown below).
ClassPathResource resorce = new ClassPathResource ("beansconfig.xml");
BeanFactory factory = new XmlBeanFactory(resource);

ClassPathXmlApplicationContext:

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
        new String[] {"applicationContext.xml", "applicationContext-part2.xml"});

//an ApplicationContext is also a BeanFactory.
BeanFactory factory = (BeanFactory) appContext;

Note BeanFactory is not recomended for use in latest Spring versions. It is there only for backward compatability. ApplicationContext is preferred over this because ApplicationContext provides more advance level features which makes an application enterprise level application.

Autowiring vs new Object Keyword

Autowiring new Object()
decouples object creation and life-cycle from object binding and usage Using new Keyword creates new Object everytime.The object graph grows over a period of time.Consider UserDaoImpl perhaps needs a Hibernate session, which needs a DataSource, which needs a JDBC connection – it quickly becomes a lot of objects that has to be created and initialized over and over again. When you rely on new in your code
Autowiring offers object at different scopes – Singleton, request and prototype All objects are JVM Scope

How Autowiring works
The autowiring happens when the application starts up, during the time of deployment.When it sees @Autowired, Spring will look for a class that matches the property in the applicationContext, and inject it automatically.

Lets see a example where the dependencies are resolved by XML and annotation
ApplicationContext.xml

<beans ...>
    <bean id="userService" class="com.foo.UserServiceImpl"/>
    <bean id="fooController" class="com.foo.FooController"/>
</beans>

When it sees @Autowired, Spring will look for a class that matches the property in the applicationContext, and inject it automatically. If you have more than 1 UserService bean, then you’ll have to qualify which one it should use.

FooController.java

public class FooController 
{
    // You could also annotate the setUserService method instead of this
    @Autowired
    private UserService userService;

    // rest of class goes here
}

Things to Note while Autowiring

  1. Marks a constructor, field, setter method or config method as to be autowired by Spring’s dependency injection facilities.
  2. Only one constructor (at max) of any given bean class may carry this annotation, indicating the constructor to autowire when used as a Spring bean. Such a constructor does not have to be public.
  3. Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public.
  4. •In the case of multiple argument methods, the ‘required’ parameter is applicable for all arguments.

Annotation or XML
For instance, if using Spring, it is entirely intuitive to use XML for the dependency injection portion of your application. This gets the code’s dependencies away from the code which will be using it, by contrast, using some sort of annotation in the code that needs the dependencies makes the code aware of this automatic configuration.

However, instead of using XML for transactional management, marking a method as transactional with an annotation makes perfect sense, since this is information a programmer would probably wish to know. But that an interface is going to be injected as a SubtypeY instead of a SubtypeX should not be included in the class, because if now you wish to inject SubtypeX, you have to change your code, whereas you had an interface contract before anyways, so with XML, you would just need to change the XML mappings and it is fairly quick and painless to do so.

I haven’t used JPA annotations, so I don’t know how good they are, but I would argue that leaving the mapping of beans to the database in XML is also good, as the object shouldn’t care where its information came from.If an annotation provides functionality and acts as a comment in and of itself, and doesn’t tie the code down to some specific process in order to function normally without this annotation, then go for annotations. For example, a transactional method marked as being transactional does not kill its operating logic, and serves as a good code-level comment as well. Otherwise, this information is probably best expressed as XML, because although it will eventually affect how the code operates, it won’t change the main functionality of the code, and hence doesn’t belong in the source files.

IoC is a generic term meaning rather than having the application call the methods in a framework, the framework calls implementations provided by the application.Inversion of Control (IoC) means any sort of programming style where an overall framework or run-time controlled the program flow.

Dependency Injection is a Type of IoC

IoC means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside service (for example, xml file or single app service).

DI means the IoC principle of getting dependent object is done without using concrete objects but abstractions (interfaces). This makes all components chain testable, cause higher level component doesn’t depend on lower level component, only from interface.

Techniques to implement inversion of control

  1. using a factory pattern
  2. using a service locator pattern
  3. using a dependency injection of any given below type:
    1. a constructor injection
    2. a setter injection
    3. an interface injection

DI is a form of IoC, where implementations are passed into an object through constructors/setters/service look-ups, which the object will ‘depend’ on in order to behave correctly.

IoC without using DI, for example would be the Template pattern because the implementation can only be changed through sub-classing.

DI Frameworks are designed to make use of DI and can define interfaces (or Annotations in Java) to make it easy to pass in implementations.

  1. The Way aspect function calls are made are through proxy classes internally
  2. Internally the Spring framework creates proxy classed and calls to the code generated as per the xml are run in proxy class methods before the actual class are called
  3. In the below example in DrawingApp.java I try to create a object for the class circle by invoking factoryService getBean Method
  4. This method returns a Object of class ShapeServiceProxy with the custom methods for xml code added

ShapeService.java

package com.mugil.shapes;

public class ShapeService {
	private Circle objCircle;
	private Triangle objTriangle;
		
	public Circle getObjCircle() {
		return objCircle;
	}
	public void setObjCircle(Circle objCircle) {
		this.objCircle = objCircle;
	}
	public Triangle getObjTriangle() {
		return objTriangle;
	}
	public void setObjTriangle(Triangle objTriangle) {
		this.objTriangle = objTriangle;
	}	
}

ShapeServiceProxy.java

package com.mugil.shapes;

public class ShapeServiceProxy extends ShapeService {
	
	public Circle getObjCircle() {
		new LoggingAspect().getLogMessage();
		return super.getObjCircle();
	}
}

DrawingApp.java

package com.mugil.shapes;

public class DrawingApp
 {
	public static void main(String[] args) 
        {
		FactoryService objFactSer = new FactoryService();
		ShapeService objSS = (ShapeService)objFactSer.getBean("ShapeService");
		objSS.getObjCircle();
	}
}

FactoryService.java

package com.mugil.shapes;

public class FactoryService {
	
	public Object getBean(String className)
	{
		if(className.equals("Circle"))
			return new Circle();
		else if(className.equals("Triangle"))
			return new Triangle();
		else if(className.equals("DrawingApp"))
			return new DrawingApp();
		else if(className.equals("ShapeService"))
			return new ShapeServiceProxy();
			
		return null;
	}
}