## 8.1、場景模擬 ### 8.1.1、UserDao介面及實現類  ``` package org ...
8.1、場景模擬
8.1.1、UserDao介面及實現類
package org.rain.spring.dao;
/**
* @author liaojy
* @date 2023/8/5 - 18:32
*/
public interface UserDao {
void saveUser();
}
package org.rain.spring.dao.impl;
import org.rain.spring.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* @author liaojy
* @date 2023/8/5 - 18:33
*/
@Repository
public class UserDaoImpl implements UserDao {
public void saveUser() {
System.out.println("保存成功");
}
}
8.1.2、UserService介面及實現類
package org.rain.spring.service;
/**
* @author liaojy
* @date 2023/8/5 - 18:35
*/
public interface UserService {
void saveUser();
}
package org.rain.spring.service.impl;
import org.rain.spring.dao.UserDao;
import org.rain.spring.service.UserService;
import org.springframework.stereotype.Service;
/**
* @author liaojy
* @date 2023/8/5 - 18:36
*/
@Service
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void saveUser() {
userDao.saveUser();
}
}
8.1.3、UserController
package org.rain.spring.controller;
import org.rain.spring.service.UserService;
import org.springframework.stereotype.Controller;
/**
* @author liaojy
* @date 2023/8/5 - 18:38
*/
@Controller("myUserController")
public class UserController {
private UserService userService;
public void saveUser(){
userService.saveUser();
}
}
8.1.4、bean配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--
對指定的package進行掃描,將使用組件註解的類的對象,交給spring的ioc容器來管理
-->
<context:component-scan base-package="org.rain.spring"></context:component-scan>
</beans>
8.1.5、測試
由控制台日誌可知,組件註解+組件掃描,存在尚未實現依賴註入的問題
@Test
public void testAutowireByAnnotation(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class);
userController.saveUser();
}
8.2、@Autowired註解
@Autowired:實現自動裝配功能的註解,其能夠標識的位置有三處
8.2.1、方式一:標識在成員變數上(常用)
@Autowired
private UserDao userDao;
@Autowired
private UserService userService;
8.2.2、方式二:標識在setter方法上
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
8.2.3、方式三:標識在有參構造方法上
private UserDao userDao;
@Autowired
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
8.3、@Autowired的工作流程
-
預設通過byType的方式,在IOC容器中匹配類型相同的bean,為屬性賦值
-
如果有多個類型匹配的bean,則自動轉換為通過byName的方式,在IOC容器中匹配id和屬性名相同的bean,為屬性賦值
-
如果有多個類型匹配的bean,且在IOC容器中沒有找到id和屬性名相同的bean;
則可以使用@Qualifier註解指定某個bean的id,將這個bean賦值給屬性
如果有多個類型匹配的bean,且在IOC容器中沒有找到id和屬性名相同的bean,也沒有使用@Qualifier註解指定將某個bean賦值給屬性;則會拋出異常NoUniqueBeanDefinitionException
@Autowired
@Qualifier("myUserService")
private UserService userService;
8.4、@Autowired的註意事項
在@Autowired註解中有一個屬性required,預設值為true,意思是必要完成自動裝配
如果在IOC容器中沒有匹配的bean,就會拋出異常NoSuchBeanDefinitionException
為此可以將required屬性的值設置為false,這樣能裝配就裝配,不能裝配就使用預設值
一般可以通過排查組件註解、組件掃描和@Qualifier註解,定位出為什麼在IOC容器中沒有匹配的bean
@Autowired(required = false)
private UserService userService;