面試官:@Configuration 和 @Component 的區別
昨天,一位朋友跟我回饋,在面試中被問到註解@Configuration
和@ Component
的區別。
一句話概括就是@Configuration
中所有帶@Bean
註解的方法都會被動態代理,因此呼叫該方法傳回的都是同一個實例。
理解:呼叫@Configuration
類別中的@Bean註解的方法,傳回的是同一個範例;而呼叫@Component
類別中的@ Bean
註解的方法,傳回的是一個新的實例。
「
注意:上面說的調用,而不是從spring容器中獲取!見最下面的範例1 及範例2
下面看看實現的細節。
@Configuration 註解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { String value() default ""; }
從定義來看,@Configuration
註解本質上還是@Component
,所以<context:component-scan/>
或@ComponentScan
都能處理@Configuration
#註解的類別。
@Configuration
標記的類別必須符合下面的要求:
配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理)。 配置类不能是final 类(没法动态代理)。 配置注解通常为了通过 @Bean
注解生成 Spring 容器管理的类,配置类必须是非本地的(即不能在方法中声明,不能是 private)。 任何嵌套配置类都必须声明为static。 @Bean
方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有@Configuration
,也不会被特殊处理,只会作为普通的 bean)。
@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 注解
@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 实例。
示例 1:调用@Configuration类中的@Bean注解的方法,返回的是同一个示例
第一个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

示例 2 :调用@Component类中的@Bean注解的方法,返回的是一个新的实例。
测试代码,只需要将@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中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

呼叫@Configuration類別中的@Bean註解的方法,傳回的是同一個範例;而呼叫@Component類別中的@Bean註解的方法,傳回的是一個新的實例。

一、基礎的動態引入元件:簡單的動態引入的意思是,前端知道要引入哪些元件,將多個元件引入到父元件中,但不渲染它,滿足一定條件後,才去在某個位置渲染指定的組件。 import{reactive,ref,shallowReactive,onActivated,defineAsyncComponent,}from'vue';constcustomModal=defineAsyncComponent(()=>import('./modal/CustomM

Vue.js是一個流行的前端框架,它提供了許多API用於組件的客製化。本文將介紹Vue中mixin、extend、component等API,幫助您掌握元件客製化的技巧。 mixinmixin是Vue中重複使用元件程式碼的一種方式。它允許我們將已經編寫的程式碼重複使用到不同的元件中,從而減少重複程式碼的編寫。例如,我們可以使用mixin來幫助我們在多個群組

一、簡單介紹@Configuration註解可以標註到類別上,當標註到類別上時,啟動Spring就會自動掃描@Configuration註解標註的類別,將其註冊到IOC容器中,並被實例化成Bean物件。如果被@Configuration註解標註的類別中存在使用@Bean註解標註的建立某個類別物件的方法,那麼,Spring也會自動執行使用@Bean註解標註的方法,將對應的Bean定義資訊註冊到IOC容器,並進行實例化。二、註解說明@Configuration註解是從Spring3.0版本開始加入的一個使Sp

react.component報錯的解決方法:1、開啟對應的react文件,找出「class Counter extends Component {static propTypes = {...」語句,將等號改為冒號;2、修改「{ "presets": ["react", "es2015", "stage-0"]}」即可。

在react中,component中文意思是“組件”,是封裝起來的具有獨立功能的UI部件;將要展示的內容,分成多個獨立部分,每一個這樣的部分,就是一個組件。元件有兩個重要的東西,一個是屬性,一個是狀態。組件的屬性是父組件給它的,存儲的是父組件對子組件的要求,在組件內部可以對屬性進行訪問,但不可以修改它;組件的狀態,由組件自行定義和使用,用來存儲組件目前狀態,組件的狀態可以修改。

@Configuration注意點1配置類別(@Configuration下的這個類別)其實相當於一個工廠,標註@Bean註解的方法相當於工廠方法考慮有如下例子:@Configuration//注意點1:配置類別其實相當於一個工廠,標註@Bean註解的方法相當於工廠方法staticclassMyConfig{@BeanpublicBean1bean1(){System.out.println("bean1()");returnnewBean1();}將來如果要產生一個bean1的實

@Configuration註解可以達到在Spring中使用xml設定檔的作用@Bean就等同於xml設定檔中的在spring專案中我們整合第三方的框架如shiro會在spring.xml設定檔中進行設定,例如:/ css/**=anon/js/**=anon/validatecode.jsp*=anon/images/**=anon/login.jsp=anon/service/**=anon/**=authc在springboot與shiro整合:@Configurationpublic
