Skip to content
Yash edited this page Oct 25, 2018 · 5 revisions

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework's IoC container.

How many types of IOC containers are there in spring?

Spring Core Container Module provides the fundamental functionalities of the spring framework. It contains the following modules:

Spring Core, Spring Bean, SpEL (Spring Expression Language), Spring Context 
  • The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object.
  • ApplicationContext is a sub-interface of BeanFactory. It adds easier integration with Spring's AOP features; message resource handling (for use in internationalization i18n), event publication; and application-layer specific contexts such as the WebApplicationContext for use in web applications.

Several implementations of the ApplicationContext interface are supplied out-of-the-box with Spring. In standalone applications it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext.

BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
                    //new XmlBeanFactory(new FileSystemResource("C:/applicationContext.xml"));
SpringBean bean1 = factory.getBean("beanId_constructor", SpringBean.class);

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
                          // new FileSystemXmlApplicationContext(new String[] {"C:/services.xml", "C:/daos.xml"});
SpringBean bean2 = context.getBean("beanId_setter", SpringBean.class);

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

<bean id="beanId_setter" class="com.github.objects.SpringBean">
    <property name="id" value="777" />
    <property name="id" value="Yash" />
</bean>

<bean id="beanId_constructor" class="com.github.objects.SpringBean">
    <constructor-arg name="id" value="8787"/>
    <constructor-arg name="id" value="Yash"/>
</bean>
Class<?> beanClass = Class.forName("com.github.objects.SpringBean");

SpringBean beanId_setter = (SpringBean) beanClass.newInstance();
beanId_setter.setId( id ); // Setting the bean properties.
beanId_setter.setName( name );

Constructor<?> beanConstructor = beanClass.getConstructor(Integer.TYPE, String.class);
SpringBean beanId_constructor = (SpringBean) beanConstructor.newInstance(id, name);
BeanFactory ApplicationContext
org.springframework.beans.factory.BeanFactory org.springframework.context.ApplicationContext
It uses Lazy initialization It uses Eager / Aggressive initialization
Beans are loaded and instantiated on-demand/lazy loading. That means during getBean() method call bean instances are created. Beans are instantiated at the time of container start-up. If we specify prototype one bean instance is created at the time of container startup. But remaining bean instances are created when we call getBean() method.
It explicitly provides a resource object using the syntax It creates and manages resource objects on its own
It doesn’t supports internationalization (i18n) It supports internationalization (i18n)
It doesn’t supports annotation based dependency It supports annotation based dependency

Dependency Injection / IoC Container

In Dependency Injection, you do not have to create your objects but have to describe how they should be created. You don’t connect your components and services together in the code directly, but describe which services are needed by which components in the configuration file. The IoC container will wire them up together.

Dependency Injection design pattern allows us to remove the hard-coded dependencies and make our application loosely coupled, extendable and maintainable. We can implement dependency injection pattern to move the dependency resolution from compile-time to runtime.

How configuration metadata is provided to the Spring container?

Configuration metadata can be provided to Spring container in following ways:

  1. XML-Based configuration: In Spring Framework, the dependencies and the services needed by beans are specified in configuration files which are in XML format. These configuration files usually contain a lot of bean definitions and application specific configuration options. They generally start with a bean tag. For example:

    <bean id="beanId_setter" class="com.github.objects.SpringBean">
        <property name="name" value="Yash" />
    </bean>

    Spring 2.0 MVC controller configuration example

    // web.xml DispatcherServlet « url-pattern [*.htm]
    // <bean name="/welcome.htm" class="com.github.yash777.HelloWorldController" />
    public class HelloWorldController extends AbstractController {
        @Override
        protected ModelAndView handleRequestInternal(request, response) throws Exception {
            ModelAndView model = new ModelAndView("viewPage");
            model.addObject("msg", "hello world");
            return model;
        }
    }
  2. Annotation-Based configuration: Spring 2.5 introduced support for annotation-based configuration metadata.
    Instead of using XML to describe a bean wiring, you can configure the bean into the component class itself by using annotations on the relevant class, method, or field declaration. By default, annotation wiring is not turned on in the Spring container. So, you need to enable it in your Spring configuration file before using it.
    For example: @Autowired /schema/context @Autowired(required=true)

    <beans>
    <context:annotation-config/> <!-- To use annotation based wiring -->
    <!-- bean definitions go here -->
    </beans>

    Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches.
    <context:annotation-config/> only looks for annotations on beans in the same application context in which it is defined. This means that, if you put <context:annotation-config/> in a WebApplicationContext for a DispatcherServlet, it only checks for @Autowired beans in your controllers, and not your services.

    @Repository, @Service, and @Controller are specializations of @Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively.

    // web.xml DispatcherServlet « url-pattern [*.htm]
    @Controller
    public class HelloWorldController {
        @RequestMapping(value = "/welcome", method = RequestMethod.GET )
        protected ModelAndView handleRequestInternal( Model model ) throws Exception {
            ModelAndView mav = new ModelAndView();
            mav.setViewName("viewPage");
            mav.addObject("msg", "hello world");
            return mav;
        }
    }

    The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>. There is usually no need to include the <context:annotation-config> element when using <context:component-scan>.

    <context:component-scan base-package="org.example"/>

    Using filters to customize scanning You can also disable the default filters by providing use-default-filters="false" as an attribute of the element. This will in effect disable automatic detection of classes annotated with @Component, @Repository, @Service, or @Controller.

  3. Java-based configuration: Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part of the core Spring Framework. Thus you can define beans external to your application classes by using Java rather than XML files. To use these new features, see the @Configuration, @Bean, @Import and @DependsOn annotations.
    The key features in Spring Framework’s new Java-configuration support are @Configuration annotated classes and @Bean annotated methods.

    1. @Bean annotation plays the same role as the <bean/> element.
    2. @Configuration classes allows to define inter-bean dependencies by simply calling other @Bean methods in the same class.
      For example:
    @Configuration
    public class AppConfig {
          @Bean(name="S1")
          public MyService Service1() {
                MyService s1 = new MyService();
                s1.setId(10);
                return s1;
          }
    }

    AnnotationConfigApplicationContext « Standalone application context, accepting annotated classes as input - in particular @Configuration-annotated classes.

    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.scan("com.github.yash777.configurations"); // For all @Configuration-annotated classes
    ctx.register(AppConfig.class); // @Configuration class to load by container
    
    ctx.registerShutdownHook();
    
    ctx.refresh();
    MyService myService = ctx.getBean("S1", MyService.class);
    myService.displayID();

    Spring configuration consists of at least one and typically more than one bean definition that the container must manage. XML-based configuration metadata shows these beans configured as <bean/> elements inside a top-level <beans/> element.

The Spring Framework supports five scopes. They are:

  • Singleton: This provides scope for the bean definition to single instance per Spring IoC container.
  • Prototype: This provides scope for a single bean definition to have any number of object instances.
  • Request: This provides scope for a bean definition to an HTTP-request.
  • Session: This provides scope for a bean definition to an HTTP-session.
  • Global-session: This provides scope for a bean definition to an Global HTTP-session.

The last three are available only if the users use a web-aware ApplicationContext.


@Autowired : When you create more than one bean of the same type and want to wire only one of them with a property you can use the @Qualifier annotation along with @Autowired to remove the ambiguity by specifying which exact bean should be wired. @Autowired @Qualifier(emp1)

@RequestMapping annotation is used for mapping a particular HTTP request method to a specific class/ method in controller that will be handling the respective request. This annotation can be applied at both levels:

  • Class level : Maps the URL of the request
  • Method level: Maps the URL as well as HTTP request method

What are the different components of a Spring application? A Spring application, generally consists of following components:

  • Interface: It defines the functions.
  • Bean class: It contains properties, its setter and getter methods, functions etc.
  • Aspect Oriented Programming (AOP): Provides the functionality of cross-cutting concerns.
  • Bean Configuration File: Contains the information of classes and how to configure them.
  • User program: It uses the function.

@Autowired(required=true)

@Autowired(required=false)
public Hello_ScopeTest(String name) {
	this.name=name;
	System.out.println("Hello_ScopeTest(name) constructor called ");
}
/*
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name
 'h2' defined in class path resource [applicationContext.xml]:
 Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]:
 : No qualifying bean of type [java.lang.String] found for dependency: expected at
 least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is 
 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for 
 dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
 Dependency annotations: {}
*/

@Autowired(required=true)
String name;
/*
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
Hello_ScopeTest(name) constructor called 
Oct 25, 2018 12:15:19 PM org.springframework.context.support.ClassPathXmlApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'h1': Injection of autowired dependencies failed; nested exception is 
org.springframework.beans.factory.BeanCreationException: Could not autowire field: 
java.lang.String com.github.yash777.standalone.Hello_ScopeTest.name; nested exception is 
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for 
dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
*/

Spring 3.0 XSD Configuration « PropertyPlaceholderConfigurer

<context:property-placeholder location="classpath:db.properties,app.properties" />
<!-- OR -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
	<list value-type="org.springframework.core.io.Resource">
		<value>classpath:config.properties</value>
		<value>classpath:mongo.properties</value>
		<value>classpath:mail.properties</value>
	</list>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>

Clone this wiki locally