深入理解bean(1)——极简解释@resource注入和手动注入的差别

问了GPT几十分钟,把一些关于bean的概念了解了一下,记录在这里。

给出一个接口和其实现类代码:

public interface MyInterface {
    void doSomething();
}

public class SpecificImpl implements MyInterface {
    private DataSource dataSource;
    private JdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void doSomething() {
        // do something with dataSource and jdbcTemplate
    }
}

接下来给出两个注入方式:

方式一:传统手动

public interface MyInterface {
    void doSomething();
}

public class SpecificImpl implements MyInterface {
    private DataSource dataSource;
    private JdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void doSomething() {
        // do something with dataSource and jdbcTemplate
    }
}
public class MyClass {
    private MyInterface myInterface;

    public MyClass() {
        this.myInterface = new SpecificImpl();
        this.myInterface.setDataSource(new DataSourceImpl());
        this.myInterface.setJdbcTemplate(new JdbcTemplateImpl());
    }

    public void doSomething() {
        myInterface.doSomething();
    }
}

方式二:用@resource注解

@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        // configure and create DataSource instance
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }
}

@Component("specificImpl")
public class SpecificImpl implements MyInterface {
    @Autowired
    private DataSource dataSource;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void doSomething() {
        // do something with dataSource and jdbcTemplate
    }
}
@Component
public class MyClass {
    @Resource(name = "specificImpl")
    private MyInterface myInterface;

    public void doSomething() {
        myInterface.doSomething();
    }
}

仔细观察上面两种方式的代码差异,当用@Resource方式进行注入的时候,相对于手动方式的优势其实就在于(因为比较杂乱,所以接下来放一大段内容,看完内容自行体会优势):

当容器启动时,会扫描所有被@Component注解标记的类,将它们实例化为bean并注册到容器中。这样,MyInterface接口的实现类SpecificImpl就成为了一个bean。

在这个过程中,Spring IoC容器会为这个bean指定一个名称,如果没有指定名称,则默认使用类名第一个字母小写的形式作为bean的名称。在这个例子中,由于使用了@Component(“specificImpl”)注解,所以bean的名称就是specificImpl。

接下来,在使用@Resource注解的时候,我们将name属性设置为specificImpl,这样就告诉了Spring IoC容器,我们需要注入的是specificImpl这个bean的实例。

当Spring IoC容器执行到这行代码时,它会在容器中查找名称为specificImpl的bean,并将其实例注入到myInterface字段中

值得注意的是,@Resource注解可以用在字段、方法和构造函数上,用于注入bean实例。在使用@Resource注解时,如果指定了name属性,则会按照名称进行注入;如果没有指定name属性,则会按照类型进行注入。如果容器中存在多个相同类型的bean,则会抛出异常。

Spring容器启动的时候,已经自动配置好了private DataSource dataSource;private JdbcTemplate jdbcTemplate;,这两个属性值在AppConfig中指定。对比手动方式,是在MyClass对象创建的时候指定。一旦这两个属性值发声变化,手动方式就需要修改所有相关代码;@Resource方式就只需要修改AppConfig类。

@Resource方式相对于手动方式,是将
this.myInterface = new SpecificImpl();
this.myInterface.setDataSource(new DataSourceImpl());
this.myInterface.setJdbcTemplate(new JdbcTemplateImpl());
这样的对象创建和初始化代码拆分出来,放在了配置文件或者其他的bean中。这样做的好处是,对象的创建和初始化逻辑不再分散在代码中,而是集中在了一个地方,使得系统更易于管理、维护和扩展。

https://juejin.cn/post/7090430080454754312,这篇文章文末有一张图,也是可以辅助理解的。放上这篇文章中的两句话:
Bean托管在Spring中一个叫IoC(Inversion of Control)的容器中;
程序是由一个个Bean构成的。

其中,IoC中的"Inversion"(中文翻译为"倒置"或"反转")在计算机科学中是指一种设计原则,即将控制权从程序代码中转移到外部容器中。在Spring框架中,这意味着应用程序的对象不再负责管理它们自己的依赖关系,而是将这个任务委托给了Spring IoC容器。这种反转控制的方式可以使应用程序更加灵活、可扩展和易于维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值