使用@Configuration在@Bean内部进行操作

Spring 3.0中有一个@Bean注释。 它允许直接在Java代码中定义Spring bean。 在浏览Spring引用时,我发现了两种使用此注释的方法 – 使用@Configuration注释的内部类和没有此注释的内部类。

本节包含以下代码:

 @Component public class FactoryMethodComponent { @Bean @Qualifier("public") public TestBean publicInstance() { return new TestBean("publicInstance"); } // omitted irrelevant method } 

在这里我们可以看到一段非常相似的代码,但现在@Configuration就在这里:

 @Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } } 

前一部分参考文献包含以下解释:

Spring组件中的@Bean方法的处理方式与Spring @Configuration类中的对应方式不同。 不同之处在于,使用CGLIB不会增强@Component类来拦截方法和字段的调用。 CGLIB代理是调用@Configuration类@Bean方法中的方法或字段创建对协作对象的bean元数据引用的方法。 使用普通的Java语义不会调用方法。 相反,在@Component类@Bean方法中调用方法或字段具有标准Java语义。

但CGLIB是应用程序开发人员不应该意识到的一种内部东西(当然,在理想的世界中)。 据我所知,在两种情况下,Spring调用使用@Bean注释的方法来创建Spring bean,在这两种情况下,这些实例都会注入协作者。

所以我的问题是,作为两个案例之间的应用程序开发人员,我什么不同

不同之处在于,使用@Configuration您可以从另一个方法调用一个@Bean方法,并获得一个完全初始化的实例,如下所示:

 public class Foo { @Value("Hello, world!") public String value; } @Configuration public class Config { @Bean public Foo createFoo() { Foo foo = new Foo(); System.out.println(foo.value); // Prints null - foo not initialized yet return foo; } @Bean public Bar createBar() { Foo foo = createFoo(); System.out.println(foo.value); // Prints Hello, world! - foo have been initialized by the interceptor return new Bar(foo); } } 

@Bean [实例方法]里面@Component – 一个方法用@Bean实例调用其他方法@Bean实例,那么它将是简单的java语义调用,即对象不会被Spring容器返回,这将是从java实例工厂正常返回方法,因为Component类不扩展CGLIB。

@Configuration中的@Bean [实例方法] – 在这种情况下,spring容器将返回对exisiting对象的引用。 它不会是正常的java sematic调用。

@Bean on配置和组件类中的静态方法 – 在这种情况下,@ Bean方法永远不会被Configuration类和Component Sterotype类中的容器拦截。