问题
I know springs AnnotationConfigApplicationContext
is capable of accepting not only @Configuration
classes as input but also plain @Component
classes and classes annotated with JSR-330 metadata.
I have created AppConfig.java below without @Configuration annotation.
public class AppConfig {
@Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
Passed this class as my java config class to AnnotationConfigApplicationContext
, it accepted and registered my service beans.
I did some modification on above same AppConfig like below.
@Component
public class AppConfig {
@Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
passed AppConfig to AnnotationConfigApplicationContext, it accepted and registered my service beans.
Question:
AnnotationConfigApplicationContext
class is accepting the java config class with@Configuration
, without@Configuration
and with @Component annotations, what is the difference between@Component
and@Configuration
?Why is it Accepting even without
@Configuration
annotation?When to use
@Configuration
, and when to use @Component as java config class?
回答1:
@Component
Indicates that an annotated class is a "component".
That is, in a context where component scanning is enabled, Spring generates bean definitions for @Component
annotated types. These bean definitions end up being turned into beans.
@Configuration, which is itself annotated with
Indicates that a class declares one or more
@Bean
methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, [...]
So any @Configuration
type, for which Spring generates a bean, acts as a factory for beans.
The javadoc of @Bean states
@Bean
methods may also be declared within classes that are not annotated with@Configuration
. For example, bean methods may be declared in a@Component
class or even in a plain old class. In such cases, a@Bean
method will get processed in a so-called 'lite' mode.Bean methods in lite mode will be treated as plain factory methods by the container (similar to factory-method declarations in XML), with scoping and lifecycle callbacks properly applied. The containing class remains unmodified in this case, and there are no unusual constraints for the containing class or the factory methods.
In contrast to the semantics for bean methods in
@Configuration
classes, 'inter-bean references' are not supported in lite mode. Instead, when one@Bean
-method invokes another@Bean
-method in lite mode, the invocation is a standard Java method invocation; Spring does not intercept the invocation via a CGLIB proxy. This is analogous to inter-@Transactional
method calls where in proxy mode, Spring does not intercept the invocation — Spring does so only in AspectJ mode.
So @Bean
methods have full functionality in @Configuration
annotated classes and limited functionality in @Component
annotated classes.
why it is Accepting even without @Configuration annotation?
That's how the class is designed. An ApplicationContext
is a BeanFactory
. AnnotationConfigApplicationContext
simply offers an extra way to register a bean definition.
When to use @Configuration, and when to use @Component as java config class?
These really completely separate goals. Follow the javadoc. When you need to setup an ApplicationContext
, you can use an AnnotationConfigApplicationContext
with a @Configuration
annotated class. If you simply need a bean, annotate its type with @Component
.
回答2:
@Component annotation marks the Java class as a bean, but @Configuration annotation marks the Java class containing beans (methods that have @Bean annotation).
The @Bean annotation must use with @Configuration exactly to create Spring beans.
In following class
@Component
public class AppConfig {
@Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
@Bean annotation is not any effect, and getSampleService() method will be plain old java method and will not be singleton, because as i mentioned, @Bean annotation must use with @Configuration, so it must be repaired as following:
@Configuration
public class AppConfig {
@Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
so replacing @Configuration annotation with any other annotation, or removing it, just make @Bean annotation ineffective and getSampleService() method will not be singleton anymore.
来源:https://stackoverflow.com/questions/26183635/java-component-class-and-configuration-class-with-annotationconfigapplicationc