(十七)自动装配-@Resource@Inject

这篇博客探讨了Spring框架中自动装配的两种方式——@Resource和@Inject。@Resource默认按组件名称进行装配,不支持@Primary和@Autowired的required=false特性。而@Inject来自JSR330,功能与@Autowired相似,但支持@Primary,不支持required=false。两者的自动注入都是通过AutowiredAnnotationBeanPostProcessor实现。博客通过实例展示了它们在自动装配和@Primary使用上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结论先行

1)、 Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解]
@Resource:
可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
没有能支持@Primary功能,没有支持@Autowired(reqiured=false);
@Inject:
需要导入javax.inject的包,和Autowired的功能一样。支持@Primary功能,但是没有required=false的功能;

<dependency>
	<groupId>javax.inject</groupId>
	<artifactId>javax.inject</artifactId>
	<version>1</version>
</dependency>

2)、@Autowired:Spring定义的; @Resource、@Inject都是java规范

3)、注解自动注入的原理都是 AutowiredAnnotationBeanPostProcessor这个BeanPostProcessor解析完成的;

@Resource

bean定义

package com.ouyangxizhu.service;

import com.ouyangxizhu.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class BookService {
//    @Qualifier("bookDao")
//    @Autowired(required = false)
    @Resource
    private BookDao bookDao;

    @Override
    public String toString() {
        return "BookService{" +
                "bookDao=" + bookDao +
                '}';
    }
}

package com.ouyangxizhu.dao;

import org.springframework.stereotype.Repository;

//名字默认是类名首字母小写
@Repository
public class BookDao {
    private int label = 1;

    public int getLabel() {
        return label;
    }

    public void setLabel(int label) {
        this.label = label;
    }

    @Override
    public String toString() {
        return "BookDao{" +
                "label=" + label +
                '}';
    }
}

配置类

package com.ouyangxizhu.config;

import com.ouyangxizhu.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;

//@ComponentScan({"com.ouyangxizhu.controller","com.ouyangxizhu.service"})
@ComponentScan({"com.ouyangxizhu.controller","com.ouyangxizhu.service","com.ouyangxizhu.dao"})
public class MainConfigResourceInject {
    //这里用bean属性定义id为bookDao2和将方法改成bookDao2效果一样
    @Primary
    @Bean("bookDao2")
    public BookDao bookDao(){
        BookDao bookDao = new BookDao();
        bookDao.setLabel(2);
        return bookDao;
    }

}

启动类

package com.ouyangxizhu;

import com.ouyangxizhu.config.MainConfigAutowiredQualifierPrimary;
import com.ouyangxizhu.config.MainConfigResourceInject;
import com.ouyangxizhu.service.BookService;
import com.ouyangxizhu.utils.PrintBeanDefinitionNamesUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTestResourceInject {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigResourceInject.class);
        System.out.println("================");
        BookService bookService = (BookService) context.getBean(BookService.class);
        System.out.println(bookService);
        PrintBeanDefinitionNamesUtils.printBeanNames(context);
    }
}

结果

八月 05, 2020 10:50:00 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0: startup date [Wed Aug 05 22:50:00 CST 2020]; root of context hierarchy
八月 05, 2020 10:50:00 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
================
BookService{bookDao=BookDao{label=1}}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigResourceInject
bookController
bookService
bookDao
bookDao2

结果说明

可以自动注入,但是不支持@Primary(如果支持BookDao的label应该是2)

@Inject

bean定义

package com.ouyangxizhu.service;

import com.ouyangxizhu.dao.BookDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.inject.Inject;

@Service
public class BookService {
//    @Qualifier("bookDao")
//    @Autowired(required = false)
//    @Resource
    @Inject
    private BookDao bookDao;

    @Override
    public String toString() {
        return "BookService{" +
                "bookDao=" + bookDao +
                '}';
    }
}

结果

八月 05, 2020 10:53:34 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0: startup date [Wed Aug 05 22:53:34 CST 2020]; root of context hierarchy
八月 05, 2020 10:53:34 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
================
BookService{bookDao=BookDao{label=2}}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigResourceInject
bookController
bookService
bookDao
bookDao2

结果

可以自动注入,并支持@Primary注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值