springboot @Configuration和@Componment的区别及说明

 更新时间:2024年06月04日 08:59:11   作者:@Ycoder  
这篇文章主要介绍了springboot @Configuration和@Componment的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

@Configuration和@Componment的区别

@Configuration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}
public class Car {

    private int id;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

public class Driver {

    private int id;

    private String name;

    private Car car;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyTestConfig {

    @Bean
    public Driver driver() {
        Driver driver = new Driver();
        driver.setId(1);
        driver.setName("driver");
        driver.setCar(car());
        return driver;
    }

    @Bean
    public Car car() {
        Car car = new Car();
        car.setId(1);
        car.setName("car");
        return car;
    }

}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Component
public class MyTestConfig {
    @Bean
    public Driver driver() {
        Driver driver = new Driver();
        driver.setId(1);
        driver.setName("driver");
        driver.setCar(car());
        return driver;
    }
    @Bean
    public Car car() {
        Car car = new Car();
        car.setId(1);
        car.setName("car");
        return car;
    }

}

上面两段代码除MyTestConfig类上的注解不同之外其他都相同,但Spring对两者的处理方式是完全不一样的。

第一段代码会像我们期望的一样正常运行

因为driver()这段代码中driver.setCar(car())方法会由Spring代理执行,

Spring发现方法所请求的Bean已经在容器中,那么就直接返回容器中的Bean。

所以全局只有一个Car对象的实例。

第二段代码在执行driver()

时driver.setCar(car())不会被Spring代理,会直接调用car()方法获取一个全新的Car对象实例,所以全局会有多个Car对象的实例

造成这种差异的原因如下:

概括就是 @Configuration 中所有带 @Bean

注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。

其工作原理是:如果方式是首次被调用那么原始的方法体会被执行并且结果对象会被注册到Spring上下文中,之后所有的对该方法的调用仅仅只是从Spring上下文中取回该对象返回给调用者。

在上面的第二段代码中

driver.setCar(car())只是纯JAVA方式的调用,多次调用该方法返回的是不同的对象实例。

要修正第二段代码中的问题,可以使用@Autowired如下所示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

//@Configuration
@Component
public class MyTestConfig2 {

    @Autowired
    Car car;
    
    @Bean
    public Driver driver() {
        Driver driver = new Driver();
        driver.setId(1);
        driver.setName("driver");
        driver.setCar(car);
        return driver;
    }

    @Bean
    public Car car() {
        Car car = new Car();
        car.setId(1);
        car.setName("car");
        return car;
    }

}

总结

1. 通过@Configuration或者@Componment注解的类默认是非懒加载,可以使用@Lazy或者在@Bean上@Lazy开启懒加载;

2. 通过@Configuration注解的类默认会被CGLIB动态代理,所有被 @Bean 注解标记的方法将来都是通过代理方法进行调用,在该类中使用@Bean时为单列;

3. 通过@Componment注解的类默认不会产生动态代理,在该类中使用@Bean,是多实例的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java模拟post请求登录猫扑示例分享

    java模拟post请求登录猫扑示例分享

    这篇文章主要介绍了java模拟post请求登录猫扑的小示例,需要的朋友可以参考下
    2014-02-02
  • SpringBoot 使用hibernate validator校验

    SpringBoot 使用hibernate validator校验

    这篇文章主要介绍了SpringBoot 使用hibernate validator校验,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • SpringBoot集成Zipkin实现分布式全链路监控

    SpringBoot集成Zipkin实现分布式全链路监控

    这篇文章主要介绍了SpringBoot集成Zipkin实现分布式全链路监控的方法啊,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • 集合嵌套之ArrayList嵌套ArrayList实例

    集合嵌套之ArrayList嵌套ArrayList实例

    下面小编就为大家带来一篇集合嵌套之ArrayList嵌套ArrayList实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • spring boot读取Excel操作示例

    spring boot读取Excel操作示例

    这篇文章主要介绍了spring boot读取Excel操作,结合实例形式详细分析了spring boot解析、读取Excel相关操作技巧,需要的朋友可以参考下
    2019-11-11
  • Java web实现头像上传以及读取显示

    Java web实现头像上传以及读取显示

    这篇文章主要为大家详细介绍了Java web实现头像上传以及读取显示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Java类和成员上的一些方法实例代码

    Java类和成员上的一些方法实例代码

    这篇文章主要介绍了Java类和成员上的一些方法实例代码,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • SpringBoot项目使用mybatis-plus逆向自动生成全套代码

    SpringBoot项目使用mybatis-plus逆向自动生成全套代码

    在JavaWeb工程中,每一个SSM新项目或者说是SpringBoot项目也好,都少不了model、controller、service、dao等层次的构建。使用mybatis-plus逆向可以自动生成,感兴趣的可以了解一下
    2021-09-09
  • java 集合工具类Collections及Comparable和Comparator排序详解

    java 集合工具类Collections及Comparable和Comparator排序详解

    这篇文章主要介绍了java集合工具类Collections及Comparable和Comparator排序详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06
  • Java中Spring的单例模式使用

    Java中Spring的单例模式使用

    这篇文章主要介绍了Java中Spring的单例模式使用,spring中的单例也不影响应用并发访问。大多数时候客户端都在访问我们应用中的业务对象,为减少并发控制,不应该在业务对象中设置那些容易造成出错的成员变量,下面一起进入文章了解更多详细内容吧
    2022-01-01

最新评论