Spring-IoC-DI-基于注解方式的依赖注入-(案例三:使用@Autowired注解实现根据类型实现自动装配)
案例三:使用@Autowired注解实现根据类型实现自动装配
@Autowired原理
@Autowired private UserService userService;
首先,按照类型去IOC容器中找到对应的组件,userService=ioc.getBean(UserService.class)
1) 找到一个找到就赋值
2) 没找到,抛异常
3) 找到多个?
再按照成员变量名(userService)作为id继续匹配?userService=ioc.getBean("userService",userService.class);
1)匹配上就赋值
2)没有匹配上?抛异常
这时我们可以使用@Qualifier注解:指定一个名作为id,让spring别使用变量名作为id
1)找到:装配
2)找不到:抛异常
这时我们可以将@Autowired的required属性设置为false
找到就装配
找不到就装配null
@Autowired标注的自动装配的属性默认是一定装配上的
可以将@Autowired的required属性设置为false(注意空指针异常问题)
找到就装配
找不到就装配null
一、测试例子一(只找到一个)
(1)编写dao类、service类,使用注解
@Repository public class UserDao { public void addBook() { System.out.println("Dao正在保存user"); } }
@Service
public class UserService {
@Autowired
private UserDao userDao;
public void add()
{
System.out.println("Service正在调用Dao");
userDao.addBook();
}
}
(2)配置文件,开启组件扫描
<context:component-scan base-package="com.orz.spring"/>
(3)测试
@Test public void test1() { ConfigurableApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml"); UserService userService = applicationContext.getBean("userService", UserService.class); userService.add(); }
(4)结果
Service正在调用Dao
Dao正在保存user
二、测试例子二(找到多个)
(1)编写两个dao类、一个service类
@Repository public class UserDao { public void addBook() { System.out.println("Dao正在保存user"); } }
@Repository public class UserDaoExt extends UserDao { @Override public void addBook() { System.out.println("UserDaoExt正在为你添加user"); } }
@Service public class UserService { @Autowired private UserDao Dao2; public void add() { System.out.println("Service正在调用Dao"); Dao2.addBook(); } }
(2)配置文件,开启组件扫描
<context:component-scan base-package="com.orz.spring"/>
(3)测试
@Test public void test1() { ConfigurableApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml"); UserService userService = applicationContext.getBean("userService", UserService.class); userService.add(); }
(4)结果
NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.orz.spring.dao.UserDao' available: expected single matching bean but found 2: userDao,userDaoExt
(5)修改service
@Service public class UserService { @Autowired private UserDao userDaoExt; public void add() { System.out.println("Service正在调用Dao"); userDaoExt.addBook(); } }
Service正在调用Dao
UserDaoExt正在为你添加user
三、测试例子三(找到多个,都不匹配)使用@Qualifier注解指定id
@Qualifier(value = "userDaoExt") @Autowired private UserDao Dao2; public void add() { System.out.println("Service正在调用Dao"); Dao2.addBook(); }
Service正在调用Dao
UserDaoExt正在为你添加user
四、测试例子四(使用了@Qualifier注解都没有匹配)
这时我们可以将@Autowired的required属性设置为false
@Service public class UserService { @Qualifier(value = "userDaoExt2") @Autowired private UserDao Dao2; public void add() { System.out.println("Service正在调用Dao"); System.out.println(Dao2); } }
@Test public void test1() { ConfigurableApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml"); UserService userService = applicationContext.getBean("userService", UserService.class); userService.add(); }
NoSuchBeanDefinitionException: No qualifying bean of type 'com.orz.spring.dao.UserDao'
available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value="userDaoExt2"),
@org.springframework.beans.factory.annotation.Autowired(required=true)}
修改service类,将@Autowired的required属性设置为false
@Service public class UserService { @Qualifier(value = "userDaoExt2") @Autowired(required = false) private UserDao Dao2; public void add() { System.out.println("Service正在调用Dao"); System.out.println(Dao2); } }
Service正在调用Dao null
(注意空指针异常问题)