[Recipe] Factory Beans in Spring with Java Configuration

Problem: 

Implement factory pattern in Spring when using Java configuration. 

Solution Summary: 

Factory design patterns help you create objects without using the new keyword directly within your code. The factory intern will create object for you. You can read more about factory pattern @ Factory Design Patterns.

We will newly create a factory class with a method that accept a String and return the object of a class. We will create a bean for factory within the java configuration file, which will be injected to other bean methods and using this bean we will be creating other beans. In the example, I have used a maven pom file with dependencies for spring-context and have specified the compiler level as Java 8. You may even use Spring Boot to do the same example. 

Solution: 

Bean Components, Config and Main Class

Package: com.javajee.spring.service

JJWriter.java

package com.javajee.spring.service;

public interface JJWriter {

    public void write();

}

 

JJFileWriter.java

package com.javajee.spring.service;

public class JJFileWriter implements JJWriter {

    public void write() {
        System.out.println("Writing to File!!!");
    }
    
    @Override
    public String toString(){
        return "Writing to File!!!";
    }

}

 

JJDatabaseWriter.java

package com.javajee.spring.service;

public class JJDatabaseWriter implements JJWriter {

    public void write() {
        System.out.println("Writing to Database!!!");
    }
    
    @Override
    public String toString(){
        return "Writing to Database!!!";
    }
}

 

WriterFactory.java

package com.javajee.spring.service;

public class WriterFactory {

    public JJWriter getWriter(String str) {
        switch (str) {
        case "file":
            return new JJFileWriter();
        case "db":
            return new JJDatabaseWriter();
        default:
            return null;
        }
    }

}

 

Package: com.javajee.spring.controller

WriterController.java

package com.javajee.spring.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.javajee.spring.service.JJWriter;

@Controller
public class WriterController {

    @Autowired
    JJWriter writer;
    
    public void write(){
        writer.write();
    }

}

 

Package: com.javajee.spring.config

DemoConfig.java

package com.javajee.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;

import com.javajee.spring.service.JJWriter;
import com.javajee.spring.service.WriterFactory;

@Configuration
@ComponentScan(basePackages="com.javajee.spring")
@PropertySource("classpath:/application.properties")
public class DemoConfig {
    
    @Bean
    public WriterFactory getWriterFactory(){
        return new WriterFactory();
    }
    
    @Bean
    @Profile("fileprofile")
    public JJWriter getJJFIleWriter(WriterFactory factory)
    {
        return factory.getWriter("file");
    }
    
    @Bean
    @Profile({"default","dbprofile"})
    public JJWriter getJJDatabaseWriter(WriterFactory factory)
    {
        return factory.getWriter("db");
    }

}

 

Package: com.javajee.spring

Main class: JJWriterMain.java

package com.javajee.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.javajee.spring.config.DemoConfig;
import com.javajee.spring.controller.WriterController;
import com.javajee.spring.service.JJWriter;

public class JJWriterMain {
    
    @Autowired
    JJWriter writer;

    public static void main(String[] args) {
        
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);

        WriterController writerController = context.getBean("writerController", WriterController.class);

        writerController.write();
        
        context.close();

    }

}

 

Note:

In this example, I have used annotations and Java configuration. However, factory implementation makes more sense in xml configuration due to some useful tag support provided by Spring xml configuration.

This example also makes use of many other annotations and concepts we have learned in this section like controller, componentscan, configuration, bean, profile, autowired etc. We will refactor the code into different packages and show the use of annotations like @Controller. Note that, technically you can use @Component or any other layer based annotations here. You can use @ComponentScan for all of these annotations. I have used the same application.properties file with a single line for activating the profile: spring.profiles.active=dbprofile. I have specified the file through @PropertySource annotation over my java configuration file. 

Recipe Tags: 

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)