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

为什么要用自动注入,因为在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



 
	


其实就是说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个接口实现类的,一个业务类的



测试类调用并执行

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"就是按名称注入了
Spring自动注入,类型注入、名称注入(两种方式)_第1张图片
第二种名称注入
@Resource(默认按照名称注入) 是JavaEE的,不是Spring的,Spring也支持

你可能感兴趣的:(测开)