Tuesday, February 13, 2018

Bean Scope


singleton

  • Scopes a single bean definition to a single object instance per Spring IoC container.

prototype

  • Scopes a single bean definition to any number of object instances.

request

  • Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.

session

  • Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

global session

  • Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.

bean factory, Bean Injection,

What is a bean factory?


Often seen as an ApplicationContext
BeanFactory is not used directly often
ApplicationContext is a complete superset of bean factory methods
Same interface implemented
Offers a richer set of features
Spring uses a BeanFactory to create, manage and locate “beans” which are basically instances of a class
Typical usage is an XML bean factory which allows configuration via XML files


How are beans created?


Beans are created in order based on the dependency graph
Often they are created when the factory loads the definitions
Can override this behavior in bean

<bean class=“className” lazy-init=“true” />

You can also override this in the factory or context but this is not recommended
Spring will instantiate beans in the order required by their dependencies
app scope singleton - eagerly instantiated at container startup
lazy dependency - created when dependent bean created
VERY lazy dependency - created when accessed in code

How are beans injected?


A dependency graph is constructed based on the various bean definitions
Beans are created using constructors (mostly no-arg) or factory methods
Dependencies that were not injected via constructor are then injected using setters
Any dependency that has not been created is created as needed

Multiple bean config files


There are 3 ways to load multiple bean config files (allows for logical division of beans)
Load multiple config files from web.xml

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/WEB-INF/spring-config.xml, classpath:/WEB-INF/applicationContext.xml</param-value>
</context-param>

Use the import tag


<import resource="services.xml"/>

Load multiple config files using Resources in the application context constructor

Recommended by the spring team

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

Bean properties?

The primary method of dependency injection

Can be another bean, value, collection, etc.

<bean id="exampleBean" class="org.example.ExampleBean">
       <property name="anotherBean">
    <ref bean="someOtherBean" />
       </property>
</bean>

This can be written in shorthand as follows

<bean id="exampleBean" class="org.example.ExampleBean">
       <property name="anotherBean" ref="someOtherBean" />
</bean>

Monday, February 12, 2018

Bean and Bean definition

What is a bean?


Typical java bean with a unique id
In spring there are basically two types
  • Singleton
One instance of the bean created and referenced each time it is requested
  • Prototype (non-singleton)
New bean created each time
Same as new ClassName()


What is a bean definition?

Defines a bean for Spring to manage

Key attributes

  • class (required): fully qualified java class name
  • id: the unique identifier for this bean
  • configuration: (singleton, init-method, etc.)
  • constructor-arg: arguments to pass to the constructor at creation time
  • property: arguments to pass to the bean setters at creation time
  • Collaborators: other beans needed in this bean (a.k.a dependencies), specified in property or constructor-arg
Typically defined in an XML file

Sample bean definition


<bean id="exampleBean" class=”org.example.ExampleBean">
   <property name="beanOne"><ref bean="anotherExampleBean"/></property>
   <property name="beanTwo"><ref bean="yetAnotherBean"/></property>
   <property name="integerProperty"><value>1</value></property>
</bean>

public class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public void setBeanOne(AnotherBean beanOne) {
    this.beanOne = beanOne; }
public void setBeanTwo(YetAnotherBean beanTwo) {
    this.beanTwo = beanTwo; }
public void setIntegerProperty(int i) {
    this.i = i; }

}

Spring Setter and Constructor Injection Example

Setter Injection

Employee.java


/**
 * @author anthakur
 *
 */
public class Employee {
    private int id;
    private String name;
    private int salary;



    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";
    }
   
}

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:component-scan base-package="com.bebo.*"></context:component-scan>
    <context:property-placeholder location="classpath:/application.properties"/>

    <bean id="employee" class="com.bebo.model.Employee">
        <property name="id" value="1">      </property> 
         <property name="name" value="Anil Thakur">      </property> 
        <property name="salary" value="100">      </property> 
       
      </bean>
</beans>


pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>SpringDemo2</groupId>
  <artifactId>SpringDemo2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
 <properties>
  <spring.version>4.0.2.RELEASE</spring.version>
  <servlet.api.version>2.5</servlet.api.version>
  <jsp.api.version>2.2</jsp.api.version>
  <jstl.version>1.2</jstl.version>
  <oracle.version>11.2.0.3</oracle.version>
 </properties>


 <dependencies>


  <!-- servlet dependency -->
  <dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>${jsp.api.version}</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
  <dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.1.1</version>
  </dependency>


  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
   <exclusions>
    <exclusion>
     <groupId>commons-logging</groupId>
     <artifactId>commons-logging</artifactId>
    </exclusion>
   </exclusions>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
  </dependency>


  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <!-- All Mail related stuff + Much more -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</artifactId>
   <version>${spring.version}</version>
  </dependency>
 </dependencies>
</project>

MainClass.java

/**
 *
 */
package com.bebo;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.bebo.model.Employee;

/**
 * @author anthakur
 *
 */
public class MainClass {

    /**
     * @param args
     */
    public static void main(String[] args) {

       
         Resource resource =new ClassPathResource("applicationContext.xml");
         BeanFactory beanFactory =new XmlBeanFactory(resource);
         
         Employee employee =(Employee) beanFactory.getBean("employee");
         System.out.println(employee.toString());
        }
}

Constructor Injection

pom.xml will be same

MainClass.java will be same


In ApplicationContext.xml

    <bean id="employee" class="com.bebo.model.Employee">
        <constructor-arg value="1" ></constructor-arg>
         <constructor-arg name="name" value="Anil" ></constructor-arg>
          <constructor-arg value="100" ></constructor-arg>      

    </bean>


Output

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Employee [id=1, name=Anil, salary=100]