Spring factory-method Explained: Bean Instantiation, Source Code & 5 Common Errors
This article explains Spring's factory-method mechanism for Bean instantiation, covering three instantiation types, static vs instance factory methods, XML and annotation configuration, source code internals including CGLIB proxying, five common errors with troubleshooting steps, and best practices for @Bean usage.
1. Three Ways of Spring Bean Instantiation
Spring supports three instantiation approaches:
Constructor instantiation : Spring calls the no-arg constructor via clazz.getDeclaredConstructor().newInstance(). Typical for @Component beans.
Static factory method instantiation : Invokes a static method on a class without needing an instance. Common for third-party libraries like Calendars.getInstance().
Instance factory method instantiation : Calls a method on another bean instance. The classic example is @Bean methods in @Configuration classes.
2. What Is factory-method?
2.1 Definition
factory-methodtells Spring which method to call to create a bean instead of using the constructor.
2.2 Static vs Instance Factory Methods
Static factory method : Method resides on the target class, static, no factory instance needed. XML: class + factory-method. Annotation: @Bean on static method.
Instance factory method : Method resides on a separate factory bean, requires factory instance first. XML: factory-bean + factory-method. Annotation: @Bean on instance method in @Configuration.
2.3 XML Configuration (Legacy)
<bean id="connection" class="com.example.ConnectionFactory" factory-method="getInstance"/>Instance factory:
<bean id="connectionFactory" class="com.example.ConnectionFactory"/>
<bean id="connection" factory-bean="connectionFactory" factory-method="getInstance"/>2.4 Annotation Configuration (Modern)
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}Key difference : Instance @Bean methods: Spring creates a CGLIB proxy to ensure the method is called only once. Static @Bean methods: No proxy needed because they don't depend on an instance.
3. Source Code: How Spring Invokes factory-method
3.1 Bean Creation Flow
Core flow: AbstractAutowireCapableBeanFactory#createBean → doCreateBean → createBeanInstance. createBeanInstance checks for factoryMethodName:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
return instantiateBean(beanName, mbd);
}3.2 instantiateUsingFactoryMethod Steps
Resolve factory method : Find the Method object by name.
Resolve factory instance :
Static factory: no instance needed.
Instance factory: fetch factory bean from BeanFactory.
Resolve method arguments : Inject parameters from container based on types.
Invoke via reflection : method.invoke(factoryBean, args).
3.3 Why CGLIB Proxy Is Required
@Configurationclasses are proxied by default to handle inter- @Bean method calls:
@Configuration
public class AppConfig {
@Bean
public A a() {
return new A(b()); // calls b()
}
@Bean
public B b() {
return new B();
}
}Without proxy, calling a() invokes b() as a plain Java method, creating a second B instance outside the container.
CGLIB proxy overrides @Bean methods to check the container first; returns existing bean if present, otherwise creates it.
This is why @Configuration(proxyBeanMethods = false) speeds up startup — no proxy is created, but it requires that @Bean methods do not call each other.
4. Common Errors & Troubleshooting
Error 1: NoSuchMethodException
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'xxx':
No static method xxx() in class com.example.XxxCauses : wrong method name, method doesn't exist, signature mismatch (parameter types).
Steps : verify spelling, confirm method exists (static vs instance), match parameter types, ensure method is public.
Error 2: BeanCurrentlyInCreationException (Circular Dependency)
BeanCurrentlyInCreationException: Error creating bean with name 'a':
Requested bean is currently in creation: Is there an unresolvable circular reference?Causes : @Bean method A calls B, B calls A; or circular config class dependencies.
Steps : inspect call chain, use @Lazy to break cycle, refactor config classes.
Error 3: @Bean Method Invoked Twice
Symptom : logs show method executed twice, two instances created.
Causes : config class missing @Configuration (only @Component), or @Configuration(proxyBeanMethods = false) with inter-method calls.
Steps : ensure @Configuration present, keep proxyBeanMethods true if methods call each other, use parameter injection instead of direct calls.
Error 4: Static @Bean Method Not Executed
Symptom : static @Bean method never runs.
Causes : static @Bean is intended for BeanFactoryPostProcessor types, must run early; wrong placement or annotation.
Steps : confirm static modifier, confirm @Bean, verify usage is for BeanFactoryPostProcessor only.
Error 5: factory-method Parameter Mismatch
UnsatisfiedDependencyException:
No matching bean of type [...] found for dependencyCauses : factory method requires parameters but Spring cannot find matching beans; parameter type mismatch.
Steps : check method parameter list, ensure each parameter type has a bean in container, match parameter names if multiple same-type beans exist.
5. When to Use factory-method
5.1 Suitable Scenarios
Third-party library beans (no Spring annotations) — use @Bean.
Complex initialization logic during bean creation.
Conditional creation of different implementations.
Classes that provide static factory methods.
Grouping related beans in a configuration class.
5.2 Unsuitable Scenarios
Your own plain classes — use @Component or @Service.
Simple no-arg constructors — no need for factory-method.
Over-splitting config classes just to use factory-method.
5.3 @Bean vs @Component
Location : @Bean in config classes; @Component on class.
Scope : @Bean for third-party classes, complex config; @Component for your own classes.
Flexibility : @Bean high (arbitrary logic); @Component low (scan-based).
Readability : @Bean centralized; @Component scattered.
Recommendation : third-party/conditional beans → @Bean; your business beans → @Component.
6. Best Practices
6.1 Keep @Bean Methods Simple
Bad: 20 lines of manual HikariConfig setup.
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public DataSource dataSource() {
return new HikariDataSource();
}Delegate configuration to @ConfigurationProperties; method only creates object.
6.2 Avoid Inter-@Bean Method Calls
Bad: return new A(b()).
Good: public A a(B b) { return new A(b); } — parameter injection is clearer and doesn't rely on CGLIB proxy.
6.3 Use static @Bean Only for BeanFactoryPostProcessor
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}Other scenarios: avoid static, prone to issues.
6.4 Configure proxyBeanMethods Appropriately
@Configuration(default true): use when methods call each other. @Configuration(proxyBeanMethods = false): pure config, no inter-method calls, faster startup. @Component: equivalent to proxyBeanMethods = false, not recommended for config classes.
7. Summary
Spring's factory-method is a core instantiation mechanism; understanding it unlocks @Bean internals.
Key Takeaways
Three instantiation modes : constructor ( @Component), static factory (third-party static methods), instance factory ( @Bean methods).
Two factory-method forms : static ( class + factory-method, no factory instance) vs instance ( factory-bean + factory-method, needs factory instance).
@Bean is factory-method : instance methods need CGLIB proxy for singleton guarantee; static methods need no proxy, used for BeanFactoryPostProcessor.
Common errors : NoSuchMethodException (name/signature), circular dependency (method call cycles), double invocation (missing @Configuration or proxyBeanMethods=false), static @Bean not running (wrong usage), parameter mismatch (missing beans).
Best practices : third-party beans → @Bean, own classes → @Component; keep @Bean simple, use @ConfigurationProperties; prefer parameter injection over method calls; tune proxyBeanMethods as needed.
Spring's @Bean looks simple but backs a full instantiation, proxying, and dependency injection mechanism. Mastering factory-method connects the dots across Spring startup, bean lifecycle, and circular dependency resolution.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Tech Workshop
Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
