Spring Framework Tutorial
Software Setup and Configuration (STS/Eclipse/IntelliJ)
Core Spring
Spring Annotations
Spring Data
Spring JDBC
Spring Security
In Spring, apart from directly instantiating beans using the constructor or setter methods, you can also define beans that are created through a static or instance factory method. This can be useful in scenarios where:
Let's dive into an example of how you can achieve Dependency Injection using factory methods in Spring.
Suppose we have a Car
interface and its implementation Sedan
:
public interface Car { void drive(); } public class Sedan implements Car { private Sedan() {} // private constructor public static Sedan createInstance() { return new Sedan(); } @Override public void drive() { System.out.println("Driving a Sedan!"); } }
In this case, the Sedan
class does not have a public constructor. We have a static createInstance
method that provides an instance.
<bean id="sedanCar" class="com.example.Sedan" factory-method="createInstance"/>
Now, let's consider an example where we delegate the creation of the bean to another factory class.
Here's our Car
interface and a factory class CarFactory
:
public interface Car { void drive(); } public class SportsCar implements Car { @Override public void drive() { System.out.println("Driving a Sports Car!"); } } public class CarFactory { public Car createSportsCar() { return new SportsCar(); } }
<bean id="carFactory" class="com.example.CarFactory"/> <bean id="sportsCar" factory-bean="carFactory" factory-method="createSportsCar"/>
In this case, the sportsCar
bean will be created using the createSportsCar
method of the carFactory
bean.
public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Car sedan = context.getBean("sedanCar", Car.class); sedan.drive(); Car sportsCar = context.getBean("sportsCar", Car.class); sportsCar.drive(); } }
Output:
Driving a Sedan! Driving a Sports Car!
By using the factory method approach, you can have more control over the instantiation of your beans. You can include conditional logic, perform additional configuration, or even pool objects if required.
Factory Method Dependency Injection in Spring:
// UserServiceFactory.java public class UserServiceFactory { public static UserService createUserService() { return new UserService(); } }
How to use factory methods for Dependency Injection in Spring:
// AppConfig.java @Configuration public class AppConfig { @Bean public UserService userService() { return UserServiceFactory.createUserService(); } }
Configuring dependencies with factory methods in Spring:
// AppConfig.java @Configuration public class AppConfig { @Bean public ProductService productService() { return ProductFactory.createProductService(); } }
FactoryBean for custom factory methods in Spring DI:
FactoryBean
for more advanced control over factory methods.// CustomFactoryBean.java public class CustomFactoryBean implements FactoryBean<UserService> { @Override public UserService getObject() throws Exception { return new UserService(); } @Override public Class<?> getObjectType() { return UserService.class; } @Override public boolean isSingleton() { return true; } }
Creating and using factory methods in Spring framework:
// AppConfig.java @Configuration public class AppConfig { @Bean public OrderService orderService() { return OrderServiceFactory.createOrderService(); } }
Using annotations for factory method injection in Spring:
@Bean
to indicate they should be used for creating Spring beans.// AppConfig.java @Configuration public class AppConfig { @Bean public ShoppingCartService shoppingCartService() { return ShoppingCartFactory.createShoppingCartService(); } }
Customizing object creation with factory methods in Spring:
// CustomFactory.java public class CustomFactory { public static CustomService createCustomService(String config) { // Custom logic based on config return new CustomService(); } }