当前位置: 代码网 > it编程>编程语言>Java > springboot @Configuration和@Componment的区别及说明

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

2024年06月10日 Java 我要评论
@configuration和@componment的区别@configuration@target({elementtype.type})@retention(retentionpolicy.run

@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,是多实例的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com