Factory Beans in Spring using Annotations Example

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.

 

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. 

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!