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 sdk安装及配置案例详解

    Java sdk安装及配置案例详解

    这篇文章主要介绍了Java sdk安装及配置案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Spring 4.0新功能:@Conditional注解详细介绍

    Spring 4.0新功能:@Conditional注解详细介绍

    Spring Boot的强大之处在于使用了Spring 4框架的新特性:@Conditional注释,此注释使得只有在特定条件满足时才启用一些配置。下面这篇文章主要给大家介绍了关于Spring4.0中新功能:@Conditional注解的相关资料,需要的朋友可以参考下。
    2017-09-09
  • java 数据结构中栈和队列的实例详解

    java 数据结构中栈和队列的实例详解

    这篇文章主要介绍了java 数据结构中栈和队列的实例详解的相关资料,主要使用数组与线性表的方法来实现,需要的朋友可以参考下
    2017-09-09
  • Java 阻塞队列BlockingQueue详解

    Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下
    2022-06-06
  • Mybatis如何使用动态语句实现批量删除(delete结合foreach)

    Mybatis如何使用动态语句实现批量删除(delete结合foreach)

    这篇文章主要介绍了Mybatis如何使用动态语句实现批量删除(delete结合foreach),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Springboot+Mybatis实现分页加条件查询功能

    Springboot+Mybatis实现分页加条件查询功能

    这篇文章主要为大家详细介绍了Springboot+Mybatis实现分页加条件查询,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • java Collection 之List学习介绍

    java Collection 之List学习介绍

    本篇文章小编为大家介绍,java Collection 之List学习介绍。需要的朋友参考下
    2013-04-04
  • java实现简单的ATM项目

    java实现简单的ATM项目

    这篇文章主要为大家详细介绍了java实现简单的ATM项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • 使用abstract格式修饰抽象方法

    使用abstract格式修饰抽象方法

    abstract是抽象的意思,用于修饰方法方法和类,修饰的方法是抽象方法,修饰的类是抽象类,这篇文章主要介绍了怎样使用abstract格式修饰抽象方法,需要的朋友可以参考下
    2023-05-05
  • Java数据结构中双向链表的实现

    Java数据结构中双向链表的实现

    这篇文章主要介绍了Java数据结构中双向链表的实现,双向链表是一种常见的数据结构,它允许在链表中的任意位置进行高效的插入和删除操作,需要的朋友可以参考下
    2022-05-05

最新评论