代码之家  ›  专栏  ›  技术社区  ›  wax

@在类内部使用@Configuration并去掉它

  •  4
  • wax  · 技术社区  · 14 年前

    有一个 @Bean Spring3.0中的注释。它允许在Java代码中直接定义springbean。在浏览SpringReference时,我发现了两种使用此注释的不同方法—在类内使用 @Configuration

    This section

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

    And here 我们可以看到一段非常相似的代码,但是现在 @配置 在以下位置:

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

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

    但是CGLIB是一种应用程序开发人员不应该意识到的内部事物(当然,在理想世界中)。据我所知,在这两种情况下,Spring都会调用带注释的方法 @豆子

    所以我的问题是 ?

    2 回复  |  直到 5 年前
        1
  •  12
  •   axtavt    14 年前

    不同之处在于 @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);
        }
    }
    
        2
  •  6
  •   Shiva Garg    9 年前

    @@Component内的Bean[instance method] -一个带有@Bean实例的方法调用另一个方法@Bean实例,那么它将是简单的java语义调用,即对象不会由Spring容器返回,它将是java实例工厂方法的正常返回,因为组件类不扩展CGLIB。

    -在这种情况下,spring容器将返回对现有对象的引用。这不是普通的java语义调用。

    -在这种情况下,@Bean方法永远不会被配置类和组件类型类中的容器截获。