昨日、友人が、アノテーション @Configuration
と @ について質問されたと私に報告してくれました。インタビュー. コンポーネント
の違い。
一文でまとめると、@Configuration
内の @Bean
アノテーションを持つすべてのメソッドは動的にプロキシされるため、このメソッドを呼び出すと次の結果が返されます。同じインスタンス。
理解: @Configuration
クラスの @Bean アノテーション付きメソッドを呼び出すと、同じ例が返されますが、@Component
クラスの @ メソッドBean
アノテーションが付けられたは、新しいインスタンスを返します。
“
注: 上記の呼び出しは Spring コンテナーから取得されたものではありません! 以下の下部の例 1 と例 2
を参照してください。実装の詳細を確認してください。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { String value() default ""; }
定義から、@構成
アノテーションは本質的に @ Component
であるため、<context:component-scan/>
または @ComponentScan
は、@Configuration
のアノテーションが付けられたクラスを処理できます。
@構成
マークされたクラスは次の要件を満たす必要があります:
@Bean
注解生成 Spring 容器管理的类,@Bean
方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration
,也不会被特殊处理,只会作为普通的 bean)。先给一个简单的示例代码:
@Configuration public class MyBeanConfig { @Bean public Country country(){ return new Country(); } @Bean public UserInfo userInfo(){ return new UserInfo(country()); } }
相信大多数人第一次看到上面 userInfo()
中调用 country()
时,会认为这里的 Country和上面 @Bean
方法返回的 Country 可能不是同一个对象,因此可能会通过下面的方式来替代这种方式:
@Autowired
private Country country;
实际上不需要这么做(后面会给出需要这样做的场景),直接调用country()
方法返回的是同一个实例。
@Component
注解并没有通过 cglib 来代理@Bean
方法的调用,因此像下面这样配置时,就是两个不同的 country
。
@Component public class MyBeanConfig { @Bean public Country country(){ return new Country(); } @Bean public UserInfo userInfo(){ return new UserInfo(country()); } }
有些特殊情况下,我们不希望 MyBeanConfig
被代理(代理后会变成WebMvcConfig$$EnhancerBySpringCGLIB$$8bef3235293
)时,就得用 @Component
,这种情况下,上面的写法就需要改成下面这样:
@Component public class MyBeanConfig { @Autowired private Country country; @Bean public Country country(){ return new Country(); } @Bean public UserInfo userInfo(){ return new UserInfo(country); } }
这种方式可以保证使用的同一个 Country 实例。
第一个bean类
package com.xl.test.logtest.utils; public class Child { private String name = "the child"; public String getName() { return name; } public void setName(String name) { this.name = name; } }
第二个bean类
package com.xl.test.logtest.utils; public class Woman { private String name = "the woman"; private Child child; public String getName() { return name; } public void setName(String name) { this.name = name; } public Child getChild() { return child; } public void setChild(Child child) { this.child = child; } }
@Configuration
类
package com.xl.test.logtest.utils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Configuration //@Component public class Human { @Bean public Woman getWomanBean() { Woman woman = new Woman(); woman.setChild(getChildBean()); // 直接调用@Bean注解的方法方法getChildBean() return woman; } @Bean public Child getChildBean() { return new Child(); } }
测试类 I
本测试类为一个配置类,这样启动项目是就可以看到测试效果的,更加快捷;也可以使用其他方式测试见下面的测试类 II
package com.xl.test.logtest.utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @Configuration public class Man { @Autowired public Man(Woman wn, Child child) { System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); System.out.println(wn.getChild() == child ? "是同一个对象":"不是同一个对象"); } }
启动项目,查看输出结果:
测试类 II
package com.xl.test.logtest.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.xl.test.logtest.utils.Child; import com.xl.test.logtest.utils.Woman; @RestController public class LogTestController { @Autowired Woman woman ; @Autowired Child child; @GetMapping("/log") public String log() { return woman.getChild() == child ? "是同一个对象":"不是同一个对象"; } }
浏览器访问项目,查看结果;输入localhost:8080/log
测试代码,只需要将@Configuration
改为@Component
即可!其他的均不变
package com.xl.test.logtest.utils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; //@Configuration @Component public class Human { @Bean public Woman getWomanBean() { Woman woman = new Woman(); woman.setChild(getChildBean()); // 直接调用@Bean注解的方法方法getChildBean() return woman; } @Bean public Child getChildBean() { return new Child(); } }
测试 :
控制台和浏览器展示,均符合预期!
最后,如果你也需要修改简历,需要模拟面试的。
以上がインタビュアー: @Configuration と @Component の違いの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。