A Bean definition contains the following piece of information called configuration metadata, which helps the container know the following things.

• The way a bean should be created.
• Life cycle details of a bean.
• Associated Bean dependencies.

The above metadata for the bean configuration is provided as a set of properties or attributes in an XML file (configuration file) which together prepare a bean definition. The following are the set of properties.

Properties Usage
class In a bean definition, it is a mandatory attribute. It is used to specify the bean class which can be used by the container to create the bean.
name In a bean definition, this attribute is used to specify the bean identifier uniquely. In XML based configuration metadata for a bean, we use the id and/or name attributes in order to specify the bean identifier(s).
scope This attribute is used to specify the scope of the objects which are created from a particular bean definition.
constructor-arg In a bean definition, this attribute is used to inject the dependencies.
properties In a bean definition, this attribute is used to inject the dependencies.
autowiring mode In a bean definition, this attribute is used to inject the dependencies.
lazy-initialization mode In a bean definition, a lazy-initialized bean informs the IoC container to create a bean instance only when it is first requested, instead of startup.
initialization method In a bean definition, a callback to be called after all required properties on the bean have been set up by the container.
destruction method In a bean definition, a callback to be used when the container that contains the bean is destroyed.

In the following example, we are going to look into an XML based configuration file which has different bean definitions. The definitions include lazy initialization (lazy-init), initialization method (init-method), and destruction method (destroy-method) as shown below. This configuration metadata file can be loaded either through BeanFactory or ApplicationContext

<?xml version = "1.0" encoding = "UTF-8"?>

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

   <!-- A simple bean definition -->
   <bean id = "..." class = "...">
      <!— Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has lazy init set on -->
   <bean id = "..." class = "..." lazy-init = "true">
      <!-- Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has initialization method -->
   <bean id = "..." class = "..." init-method = "...">
      <!-- Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has destruction method -->
   <bean id = "..." class = "..." destroy-method = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- more bean definitions can be written below -->
   
</beans>

Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

3 types of method references:

  1. Reference to a static method
  2. Reference to an instance method
  3. Reference to a constructor

Reference to a static method
Syntax

  ClassName::MethodName
import java.util.function.BiFunction;
class Arithmetic 
 {
 public static int add(int a, int b) 
 {
  return a + b;
 }
}
public class MethodReference 
{
 public static void main(String[] args) 
 {
  BiFunction < Integer, Integer, Integer > adder = Arithmetic::add;
  int result = adder.apply(10, 20);
  System.out.println(result);
 }
}

Reference to an instance method
Syntax

Object::methodName
import java.util.function.BiFunction;
class Arithmetic 
 {
 public int add(int a, int b) 
 {
  return a + b;
 }
}
public class MethodReference 
{
 public static void main(String[] args) 
 {
  Arithmetic objArithmetic = new Arithmetic();
  BiFunction < Integer, Integer, Integer > adder = objArithmetic::add;
  int result = adder.apply(10, 20);
  System.out.println(result);
 }
}

Reference to a constructor
Syntax

ClassName::new  
interface Messageable {
 Message getMessage(String msg);
}
class Message {
 Message(String msg) {
  System.out.print(msg);
 }
}
public class ConstructorReference {
 public static void main(String[] args) {
  Messageable hello = Message::new;
  hello.getMessage("Hello");
 }
}