difference between @Component and @Configuration i

2020-01-29 05:17发布

问题:

I came across two annotations provided by Spring 3 (@Component and @Configuration) I am a bit confused between these.
Here is what I read about @Component

Put this “context:component” in bean configuration file, it means, enable auto scanning feature in Spring. The base-package is indicate where are your components stored, Spring will scan this folder and find out the bean (annotated with @Component) and register it in Spring container.

So I am wondering what is the use of @Configuration then if @Controller will register my beans without the need to declare them in spring configuration xml file

回答1:

@Configuration is the heart of the Java-based configuration mechanism that was introduced in Spring 3. It provides an alternative to XML-based configuration.

So the 2 following snippets are identical:

<beans ...>
    <context:component-scan base-package="my.base.package"/>
    ... other configuration ...
</beans>

and:

@Configuration
@ComponentScan(basePackages = "my.base.package")
public class RootConfig {
    ... other configuration ...
}

In both cases Spring will scan in my.base.package and below for classes annotated with @Component or one of the other annotations that are meta-annotated with @Component such as @Service.



回答2:

From Book Pro Spring Integration

@Configuration classes are just like regular @Components classes, except that methods annotated with @Bean are used to factory beans. Note that a @Component with @Bean annotated methods works the same way, except that scopes are not respected and the @Bean methods are re-invoked (no caching in play), so @Configuration is preferred, even though it requires CGLIB



回答3:

Here is difference with full example :-

//@Configuration or @Component
public static class Config {
    @Bean
    public A a() {
        return new A();
    }
    //**please see a() method called inside b() method**
    @Bean
    public B b() {
        return new B(a());
    }
}

1) Here if Config class annotated with @configuration , than a() method and b() method , both will be called once .

2)Here if Config class annotated with @component , than b() method will be called once but a() method will be called twice .

Problem in (2) :- since we have noticed the problem with @component annotation . This second configuration (2) is totally incorrect because spring will create a singleton bean of A, but B will obtain another instance of A which is out of the spring context control.

Solution :- we can use @autowired annotation with @component annotation inside Config class .

@Component
public static class Config {
    @Autowired
    A a;

    @Bean
    public A a() {
        return new A();
    }

    @Bean
    public B b() {
        return new B(a);
    }
}


回答4:

Although this is old, but elaborating on JavaBoy And Vijay's answers, with an example:

@Configuration
public class JavaConfig {
    @Bean
    public A getA() {
        return new A();
    }
}

@Component
@ComponentScan(basePackages="spring.example")
public class Main() {
    @Bean
    public B getB() {
        return new B();
    }
    @Autowired
    JavaConfig config;

    public static void main(String[]a) {
        Main m = new AnnotationConfigApplicationContext(Main.class)
            .getBean(Main.class);
        /* Different bean returned everytime on calling Main.getB() */
        System.out.println(m.getB());
        System.out.println(m.getB());
        /* Same bean returned everytime on calling JavaConfig.getA() */
        System.out.println(m.config.getA());
        System.out.println(m.config.getA());
    }
}


回答5:

@Component is a generic stereotype annotation which can indicate any of the candidate components i.e; @Repository, @Service, @Controller and these candidates are eligible for auto-detection.

Where as @Configuration is used to create component which is used by spring framework to create the application context, internally @Configuration makes use of @Component it makes sense reason being even that's a spring component which the framework itself creates.