Spring自动注入,类型注入、名称注入(两种方式)

本文探讨了Spring自动注入的必要性,详细介绍了类型注入(@Autowired)和名称注入(@Qualifier与@Resource)的使用。通过示例说明了如何在Spring中创建接口及其多个实现类,并演示了在类中如何进行自动注入。同时,指出了类型注入可能导致的冲突问题,提出了通过名称注入来解决此类问题的方法,包括使用@Qualifier注解和配置XML文件进行默认的按名称注入。

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

为什么要用自动注入,因为在bean很多或者自定义的类很多的情况下,就要在xml文件里一直写bean并且还要将每个属性以set(构造方法)入参的方式引入bean里,这样耦合性也会变高,也比较麻烦
将类属性注入到Spring容器中有几种方式
@Autowired 按类型注入 Spring自己的注解
@Qualifier (与@Autowired搭配按名称)
@Resource 按名称注入 JavaEE的,Spring也支持,建议使用这个,全球通用的

自动注入的实现
创建一个接口BookingService

public interface BookingService {
	 void booking();
}

创建该接口的实现类QunarService ,用注解@Service将该类加入到Spring容器中托管,记得扫描包

@Service
public class QunarService implements BookingService {
@Override
public void booking(){
    System.out.println("去哪儿预定");
}
}

创建该接口的实现类ElongService ,用注解@Service将该类加入到Spring容器中托管,记得扫描包

@Service
public class ElongService implements BookingService {
@Override
public void booking() {
    System.out.println("艺龙预定");
}
}

创建该接口的实现类MeiTuanService ,用注解@Service将该类加入到Spring容器中托管,记得扫描包

@Service
public class MeiTuanService implements BookingService {
@Override
public void booking(){
    System.out.println("美团预定");
}
}

创建一个人类,将BookingService的几个接口的实现类分别用set方法、get方法、属性注入到该类中(用@Autowired自动注入),首先人这个类就要是一个bean,在xml文件中配置

public class Person {
//属性实现自动注入
@Autowired
ElongService elongService;
MeiTuanService meiTuanService;
QunarService qunarService;
Person(){}
//set方法实现自动注入
@Autowired
public void setMeiTuanService(MeiTuanService meiTuanService) {
    this.meiTuanService = meiTuanService;
}
@Autowired
Person(QunarService qunarService){
    this.qunarService=qunarService;
}
public void booking(BookingService bookingService){
    bookingService.booking();
}
}

xml文件里,引包、添加bean

<!--因为接口的实现类都在booking这个包下,所以引这个包就好但是要是想用注解		加入-->
<!--bean的类在不同包下那么就要引不同的包,保证每个类都是引包成功的-->
 <context:component-scan base-package="com.longteng.lesson2.my.booking">
	</context:component-scan>
<!--将Person类加入bean-->
<bean id="Person" class="com.longteng.lesson2.my.booking.Person"></bean>

其实就是说set方法、构造方法、属性都是可以实现自动注入的,一般情况下属性时用的最多的

类型注入的弊端
有个接口

public interface MyUserDao {
String addUserDao(String userName);
}

第一个接口实现类用注解添加为bean成功,要扫描包

@Component
public class IUserDao implements MyUserDao {
@Override
public String addUserDao(String userName){
    return userName;
}
}

第一个接口实现类用注解添加为bean成功,要扫描包

@Component
public class UserDao implements MyUserDao {
@Override
public String addUserDao(String userName){
    return userName;
}
}

业务类使用类型注入,注入的是父类接口的类型,因为父类类型可以指向子类

@Service
public class UserDaoTest {
@Autowired
MyUserDao myUserDao;
public String booking(){
    return myUserDao.addUserDao("xx");
}
}

xml中扫描包,2个接口实现类的,一个业务类的

<context:component-scan base-package="com.longteng.lesson2.my.impl"/>
<context:component-scan base-package="com.longteng.lesson2.my"/>

测试类调用并执行

public class Test {
ApplicationContext context;
@BeforeClass
public void beforeTest() {
    context = new ClassPathXmlApplicationContext("iocc.xml");
}
@org.testng.annotations.Test
public void bookingTest(){
    UserDaoTest userDaoTest=(UserDaoTest) context.getBean("userDaoTest");
    assertEquals("校验姓名","xx" ,userDaoTest.booking());
    }
}

报错,有两个目标bean,不知道该使用哪一个,因为业务类里使用的是父类接口的类型注入的,2个接口实现类都是该类型,所以要用名称注入
在这里插入图片描述

第一种名称注入
@Autowired注解结合@Qualifier注解使用
在注入bean的时候指定该bean的名称,获取bean使用的时候指定使用的是哪个bean
1 在两个接口实现类的地方设置bean名称

//设置该bean名称为iUserDao
@Component("iUserDao")
public class IUserDao implements MyUserDao {
@Override
public String addUserDao(String userName){
    return userName;
}
}

//设置该bean名称为userDao
@Component("userDao")
public class UserDao implements MyUserDao {
@Override
public String addUserDao(String userName){
    return userName;
}
}

业务实现类使用bean时指定使用哪一个

//业务类指定使用iUserDao这个bean
@Service
public class UserDaoTest {
@Autowired
@Qualifier("iUserDao")
MyUserDao myUserDao;
public String booking(){
    return myUserDao.addUserDao("xx");
}
}

xml中默认按类型注入,怎么改为按名称注入
在xml文件里的beans的最后加上 default-autowire="byName"就是按名称注入了
在这里插入图片描述
第二种名称注入
@Resource(默认按照名称注入) 是JavaEE的,不是Spring的,Spring也支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值