Showing posts with label @Required. Show all posts
Showing posts with label @Required. Show all posts

Friday, 17 August 2018

Spring dependency checking with Custom @Required Annotation | Spring Tutorial

Master Spring & Java Development!

Subscribe to Ram N Java for clean, beginner-friendly coding guides!

🔔 Subscribe to Ram N Java

Overview: Custom @Required Annotation in Spring

In the Spring Framework, dependency validation ensures that mandatory bean properties are populated at configuration time rather than failing at runtime with a NullPointerException. While Spring provides the built-in @Required annotation, developers can also create and register their own custom @Required annotations. This allows teams to enforce custom validation semantics, follow organizational naming standards, or integrate seamlessly with custom bean post-processors.

In this guide, you will learn how to define a custom required annotation, configure Spring's RequiredAnnotationBeanPostProcessor to recognize it, and enforce strict dependency checking during bean initialization.

How Custom Dependency Checking Works

Spring's dependency checking framework is highly modular and customizable:

  • Custom Annotation Declaration: You can define a standard Java retention annotation (e.g., @Mandatory) targeted at methods.
  • Post-Processor Configuration: The RequiredAnnotationBeanPostProcessor supports setting custom annotation types via its setCustomAnnotationType() property.
  • Fail-Fast Property Enforcement: If any setter method annotated with your custom annotation does not receive a property value during bean configuration, Spring raises a BeanInitializationException immediately during application startup.
  • Cleaner Architecture: Enforces architectural contracts across your service layer without coupling your domain code strictly to Spring's package namespaces.

Step-by-Step Implementation

  1. Create the Custom Annotation: Define a retention annotation applicable to methods:
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Mandatory { }
  2. Configure RequiredAnnotationBeanPostProcessor: Register the processor in Spring XML and specify your custom annotation type:
    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
      <property name="customAnnotationType" value="com.example.Mandatory"/>
    </bean>
  3. Annotate Setter Methods: Place your custom annotation on setter methods that require dependencies:
    @Mandatory
    public void setDataSource(DataSource dataSource) {
      this.dataSource = dataSource;
    }

Recommended Next Videos from Ram N Java


Click here to watch on Youtube:
https://www.youtube.com/watch?v=USltDCotopE&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:


Spring dependency checking with Custom @Required Annotation | Spring Tutorial

Spring dependency checking with Custom @Required Annotation | Spring Tutorial

Spring dependency checking with Custom @Required Annotation | Spring Tutorial

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%20http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ram.core</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringDemo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring 5 dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

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

Mandatory.java

package com.ram.custom;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory
{
}

Address.java

package com.ram.model;

public class Address
{
    private String city;
    private String state;

    public String getCity()
    {
        return city;
    }

    public void setCity(String city)
    {
        this.city = city;
    }

    public String getState()
    {
        return state;
    }

    public void setState(String state)
    {
        this.state = state;
    }

    @Override
    public String toString()
    {
        return "Address [city=" + city + ", state=" + state + "]";
    }

}

Employee.java

package com.ram.model;

import com.ram.custom.Mandatory;

public class Employee
{
    private int id;
    private String name;
    private Address address;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

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

    public Address getAddress()
    {
        return address;
    }
   
    @Mandatory
    public void setAddress(Address address)
    {
        this.address = address;
    }

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

}

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.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd">


    <bean id="address" class="com.ram.model.Address">
        <property name="city" value="TamilNadu"></property>
        <property name="state" value="Chennai"></property>
    </bean>


    <bean id="employee" class="com.ram.model.Employee">
        <property name="id" value="100"></property>
        <property name="name" value="Peter"></property>
        <!-- <property name="address" ref="address"></property> -->
    </bean>

    <bean
        class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
        <property name="requiredAnnotationType" value="com.ram.custom.Mandatory" />
    </bean>

</beans>

App.java

package com.ram.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ram.model.Employee;

public class App
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");

        System.out.println("---------------------------------------");

        Employee employee = context.getBean("employee", Employee.class);
        System.out.println(
                "Got employee object from the ApplicationContext(Spring Container)");

        System.out.println(employee);

    }

}

Output

Aug 06, 2018 9:47:19 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Mon Aug 06 09:47:19 IST 2018]; root of context hierarchy
Aug 06, 2018 9:47:19 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
Aug 06, 2018 9:47:20 AM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:758)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
    at com.ram.core.App.main(App.java:12)
Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
    at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:156)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    ... 11 more

Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_custom_required_annotation.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_custom_required_annotation

Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/476437cc0ec4e46c307e790b2c10c4099b1c066b/Spring_2018/SpringDemo_custom_required_annotation/?at=master

See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • Spring dependency checking with @Required Annotation v2 | Spring Tutorial

    Master Spring & Java Development!

    Subscribe to Ram N Java for clean, beginner-friendly coding guides!

    🔔 Subscribe to Ram N Java

    Overview: Dependency Checking with @Required

    In the Spring Framework, ensuring that all critical dependencies and configuration properties are set is crucial for preventing unexpected NullPointerException errors during runtime. Spring provides the @Required annotation to enforce mandatory bean property population at configuration time.

    In this guide, you will learn how the @Required annotation works, how to enable it in your Spring configuration, and how it enforces fail-fast validation during bean initialization.

    Understanding the @Required Annotation

    The @Required annotation provides declarative property checking with the following characteristics:

    • Applied to Setter Methods: It is placed directly above setter methods to signify that the associated bean property must be populated in XML configuration.
    • Fail-Fast Behavior: If an annotated property is not configured, Spring immediately throws a BeanInitializationException during container startup rather than failing at runtime.
    • Managed by Post-Processor: The dependency checking is performed by the RequiredAnnotationBeanPostProcessor, which inspects bean definitions before initialization.
    • Explicit Dependency Contracts: It clearly documents and enforces which properties are non-negotiable for a bean's functionality.

    Step-by-Step Implementation

    1. Annotate the Setter Method: Add @Required on setter methods in your Java bean:
      @Required
      public void setMessage(String message) {
        this.message = message;
      }
    2. Enable RequiredAnnotationBeanPostProcessor: Register the processor in your XML configuration or include <context:annotation-config />:
      <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
    3. Verify Property Wiring: Provide the property in your XML definition. If omitted, Spring halts initialization with a descriptive error.

    Recommended Next Videos from Ram N Java


    Click here to watch on Youtube:
    https://www.youtube.com/watch?v=BtmpN7TgoxM&list=UUhwKlOVR041tngjerWxVccw

    Click the below Image to Enlarge:


    Spring dependency checking with @Required Annotation v2 | Spring Tutorial

    Spring dependency checking with @Required Annotation v2 | Spring Tutorial

    Spring dependency checking with @Required Annotation v2 | Spring Tutorial

    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%20http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.ram.core</groupId>
        <artifactId>SpringDemo</artifactId>
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>SpringDemo</name>
        <url>http://maven.apache.org</url>

        <properties>
            <spring.version>5.0.2.RELEASE</spring.version>
        </properties>

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>

            <!-- Spring 5 dependencies -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>

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

    Address.java

    package com.ram.model;

    public class Address
    {
        private String city;
        private String state;

        public String getCity()
        {
            return city;
        }

        public void setCity(String city)
        {
            this.city = city;
        }

        public String getState()
        {
            return state;
        }

        public void setState(String state)
        {
            this.state = state;
        }

        @Override
        public String toString()
        {
            return "Address [city=" + city + ", state=" + state + "]";
        }

    }

    Employee.java

    package com.ram.model;

    import org.springframework.beans.factory.annotation.Required;

    public class Employee
    {
        private int id;
        private String name;
        private Address address;

        public int getId()
        {
            return id;
        }

        public void setId(int id)
        {
            this.id = id;
        }

        public String getName()
        {
            return name;
        }

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

        public Address getAddress()
        {
            return address;
        }
       
        @Required
        public void setAddress(Address address)
        {
            this.address = address;
        }

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

    }

    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.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">


        <bean id="address" class="com.ram.model.Address">
            <property name="city" value="TamilNadu"></property>
            <property name="state" value="Chennai"></property>
        </bean>


        <bean id="employee" class="com.ram.model.Employee">
            <property name="id" value="100"></property>
            <property name="name" value="Peter"></property>
            <!-- <property name="address" ref="address"></property> -->
        </bean>

        <bean
            class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />

    </beans>

    App.java

    package com.ram.core;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.ram.model.Employee;

    public class App
    {
        public static void main(String[] args)
        {
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");

            System.out.println("---------------------------------------");

            Employee employee = context.getBean("employee", Employee.class);
            System.out.println(
                    "Got employee object from the ApplicationContext(Spring Container)");

            System.out.println(employee);

        }

    }

    Output

    Aug 05, 2018 9:29:58 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sun Aug 05 09:29:58 IST 2018]; root of context hierarchy
    Aug 05, 2018 9:29:59 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
    Aug 05, 2018 9:29:59 AM org.springframework.context.support.AbstractApplicationContext refresh
    WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:758)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
        at com.ram.core.App.main(App.java:12)
    Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
        at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:156)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
        ... 11 more

    Click the below link to download the code:
    https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Required_Annotation_V2.zip?attredirects=0&d=1

    Github Link:
    https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Required_Annotation_V2

    Bitbucket Link:
    https://bitbucket.org/ramram43210/spring/src/476437cc0ec4e46c307e790b2c10c4099b1c066b/Spring_2018/SpringDemo_Required_Annotation_V2/?at=master

    See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • Tuesday, 14 August 2018

    Spring dependency checking with @Required Annotation V1 | Spring Tutorial

    Master Spring & Java Development!

    Subscribe to Ram N Java for clean, beginner-friendly coding guides!

    🔔 Subscribe to Ram N Java

    Overview: Spring Dependency Checking with @Required

    When configuring beans in the Spring Framework, missing configuration properties can cause severe runtime bugs such as unexpected NullPointerException failures. To guarantee that all required bean dependencies and properties are properly populated at configuration time, Spring provides dependency checking capabilities powered by the @Required annotation.

    In this guide, you will understand how dependency checking works with the @Required annotation, how Spring detects missing properties at container startup, and how to apply this to build robust Java enterprise applications.

    Key Concepts of Dependency Checking

    The @Required annotation enforces strict dependency contracts on bean properties:

    • Enforcing Setter Injection: Placed directly on setter methods, it mandates that the associated property must be explicitly defined in XML configuration files or through automated property definitions.
    • Early Failure Detection (Fail-Fast): Instead of failing when the bean is actually used during application execution, Spring halts during initialization by throwing a BeanInitializationException if the property was omitted.
    • Post-Processor Verification: Handled by RequiredAnnotationBeanPostProcessor, which inspects the bean properties right after instantiation and property setting.
    • Improved Code Reliability: Prevents uninitialized dependencies from escaping into business logic, leading to cleaner and more maintainable codebases.

    Step-by-Step Configuration

    1. Annotate Setter Methods: Mark the required setter method with @Required:
      @Required
      public void setStudentName(String studentName) {
        this.studentName = studentName;
      }
    2. Register RequiredAnnotationBeanPostProcessor: Enable annotation support in XML via <context:annotation-config /> or explicitly register the bean post-processor:
      <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
    3. Configure the Bean Property: Provide the <property> tag in your bean definition. If left out, Spring throws an exception on startup alerting you to the missing dependency.

    Recommended Next Videos from Ram N Java

    Click here to watch on Youtube:
    https://www.youtube.com/watch?v=Mu8-swqQTDs&index=1&list=UUhwKlOVR041tngjerWxVccw
     
    Click the below Image to Enlarge:

    Spring dependency checking with @Required Annotation V1 | Spring Tutorial

    Spring dependency checking with @Required Annotation V1 | Spring Tutorial

    Spring dependency checking with @Required Annotation V1 | Spring Tutorial
    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%20http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.ram.core</groupId>
        <artifactId>SpringDemo</artifactId>
        <packaging>jar</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>SpringDemo</name>
        <url>http://maven.apache.org</url>

        <properties>
            <spring.version>5.0.2.RELEASE</spring.version>
        </properties>

        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>

            <!-- Spring 5 dependencies -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>

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

    Address.java

    package com.ram.model;

    public class Address
    {
        private String city;
        private String state;

        public String getCity()
        {
            return city;
        }

        public void setCity(String city)
        {
            this.city = city;
        }

        public String getState()
        {
            return state;
        }

        public void setState(String state)
        {
            this.state = state;
        }

        @Override
        public String toString()
        {
            return "Address [city=" + city + ", state=" + state + "]";
        }

    }

    Employee.java

    package com.ram.model;

    import org.springframework.beans.factory.annotation.Required;

    public class Employee
    {
        private int id;
        private String name;
        private Address address;

        public int getId()
        {
            return id;
        }

        public void setId(int id)
        {
            this.id = id;
        }

        public String getName()
        {
            return name;
        }

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

        public Address getAddress()
        {
            return address;
        }
       
        @Required
        public void setAddress(Address address)
        {
            this.address = address;
        }

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

    }

    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.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">


        <bean id="address" class="com.ram.model.Address">
            <property name="city" value="TamilNadu"></property>
            <property name="state" value="Chennai"></property>
        </bean>


        <bean id="employee" class="com.ram.model.Employee">
            <property name="id" value="100"></property>
            <property name="name" value="Peter"></property>
        <!--    <property name="address" ref="address"></property> -->
        </bean>

        <context:annotation-config />

    </beans>

    App.java

    package com.ram.core;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.ram.model.Employee;

    public class App
    {
        public static void main(String[] args)
        {
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");

            System.out.println("---------------------------------------");

            Employee employee = context.getBean("employee", Employee.class);
            System.out.println(
                    "Got employee object from the ApplicationContext(Spring Container)");

            System.out.println(employee);

        }

    }

    Output

    Aug 04, 2018 10:34:25 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sat Aug 04 10:34:25 IST 2018]; root of context hierarchy
    Aug 04, 2018 10:34:25 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
    Aug 04, 2018 10:34:26 AM org.springframework.context.support.AbstractApplicationContext refresh
    WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employee' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:758)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
        at com.ram.core.App.main(App.java:12)
    Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'address' is required for bean 'employee'
        at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:156)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
        ... 11 more

    Click the below link to download the code:
    https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Required_Annotation.zip?attredirects=0&d=1

    Github Link:
    https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Required_Annotation

    Bitbucket Link:
    https://bitbucket.org/ramram43210/spring/src/eb94a9e0ae07f3c6a86034ef414051430bbfc9bc/Spring_2018/SpringDemo_Required_Annotation/?at=master

    See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • Tutorials