服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

@Configuration 和 @Component 的区别 ,别再瞎用了

日期: 来源:终码一生收集编辑:康熙

点击“终码一生”,关注,置顶公众号

每日技术干货,第一时间送达!

耗时8个月联合打造 《 2023年Java高薪课程 》,更新了 102G 视频累计更新时长 500+ 个小时,需要的小伙伴可以了解下,一次购买,持续更新,无需2次付费。


一句话概括就是 @Configuration 中所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。

理解:调用@Configuration类中的@Bean注解的方法,返回的是同一个示例;而调用@Component类中的@Bean注解的方法,返回的是一个新的实例。

“注意:上面说的调用,而不是从spring容器中获取! 见最下面的示例 1 及 示例 2


下面看看实现的细节。

1

@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)。

2

@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() 方法返回的是同一个实例。

3

@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();
 }
}


测试 :


控制台和浏览器展示,均符合预期!

来源:blog.csdn.net/qq_29025955/article/details/128818957

—END—

 

【福利】2023 高薪课程,全面来袭(视频+笔记+源码)


【福利】2023 高薪课程,全面来袭(视频+笔记+源码)


PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。




往期推荐



11 款顶级 MySQL 图形化工具汇总,总有一款适合你!

面试官:为什么不建议用 equals 判断对象相等?

用上这几个开源管理系统做项目,领导看了直呼专业!

京东技术:MySQL性能优化浅析及线上案例讲解

ChatGPT修bug横扫全场,准确率达78%!程序员该开心还是难过?

线程池中线程抛了异常,该如何处理?

详解 Java 泛型,写得太好了!


相关阅读

  • 学会 IDEA 这 30 个神技,撸码效率直接起飞

  • 点击“终码一生”,关注,置顶公众号每日技术干货,第一时间送达!耗时8个月联合打造 《 2023年Java高薪课程 》,已更新了 102G 视频,累计更新时长 500+ 个小时,需要的小伙伴可以了解下
  • 京都大学|去除SiC氧化膜界面缺陷的解决方案

  • 点击蓝字 关注我们在SiC晶圆和晶体管的制造过程中,需要对SiC表面进行氧化,碳化硅 MOSFET 热氧化过程中,会在表面形成SiO2氧化膜,这被视为SiC的一大优点。但此时氧化膜与SiC之间
  • 爱了爱了....

  • 先来吐槽一波。最近不是有很多大神都开始扎堆出新书了么,我今天去看了一下签约作者新书榜,真的是恐怖如斯啊.....这里面我大概数了一下这里面有1位白金作者,6位大神,还有至少6位
  • 上海买房,请认准工科男

  • 环线深耕上海楼市多年,渐渐的有了自己影响力,已经帮助上千组客户安家上海。任何一个品牌有影响力后,都会形成自己独特的标签。环线的标签很多,比如“普陀黑”。01开心的是环线品
  • 短短几个字,感知基金公司的企业文化

  • 《狂飙》出圈——你想要正能量,他有扫黑除恶的主旋律;你想看爽文男主,他教你认干爹、看《孙子兵法》,实现屌丝逆袭;你想看男男基情,他有霸道老板和耿直警官的CP满屏;甚至,还可以在大
  • 玩归玩闹归闹,别跟央妈开玩笑

  • 继续跟踪美国通胀和加息进程:其实现在看总量已经没啥额外认知了,我们重点关注「结构」和「边际变化」。结构是啥?商品已经不通胀了,支撑通胀的是房租。美国自有住房率才60%多,所
  • 新书推荐 | 《做质性研究,先读我》

  • 编辑推荐EDITOR'S RECOMMENDATIONS《做质性研究,先读我》的作者秉持以下观点:质性研究方法的共同核心都在于“质性地”而不是“量化地”去搜集和处理数据。在质性研究中,数据
  • 新书推荐 | 案例研究:原理与实践(修订版)

  • 编辑推荐EDITOR'S RECOMMENDATIONS尽管人们对经验世界的大多数认识源自案例研究,并且社会科学各学科产生的大部分成果还将继续由案例研究构成,但是,学者们对案例研究方法总体

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • @Configuration 和 @Component 的区别 ,别再瞎用了

  • 点击“终码一生”,关注,置顶公众号每日技术干货,第一时间送达!耗时8个月联合打造 《 2023年Java高薪课程 》,已更新了 102G 视频,累计更新时长 500+ 个小时,需要的小伙伴可以了解下
  • 程序员健康最佳作息表,建议收藏!!

  • 点击“终码一生”,关注,置顶公众号每日技术干货,第一时间送达!耗时8个月联合打造 《 2023年Java高薪课程 》,已更新了 102G 视频,累计更新时长 500+ 个小时,需要的小伙伴可以了解下
  • 顶级Javaer都在使用的类库,真香!

  • 点击“终码一生”,关注,置顶公众号每日技术干货,第一时间送达!耗时8个月联合打造 《 2023年Java高薪课程 》,已更新了 102G 视频,累计更新时长 500+ 个小时,需要的小伙伴可以了解下
  • 学会 IDEA 这 30 个神技,撸码效率直接起飞

  • 点击“终码一生”,关注,置顶公众号每日技术干货,第一时间送达!耗时8个月联合打造 《 2023年Java高薪课程 》,已更新了 102G 视频,累计更新时长 500+ 个小时,需要的小伙伴可以了解下