- //@Controller("controller")
- @Controller
- public class UserController {
-
- private UserService userService;
-
-
- }
- @Service
- public class UserServiceImpl implements UserService {
-
- private UserDao userDao;
-
- }
第二步:在UserController里面有userService对象
userService对象调用方法saveUser(); 调用保存用户信息方法 userService.saveUser();
- @Controller
- public class UserController {
-
- private UserService userService;
-
-
- public void saveUser(){
- userService.saveUser();
- }
- }
第三步:UserService接口里面创建方法 创建保存用户信息方法
- package com.atguigu.spring.service;
-
- public interface UserService {
-
- /**
- * 保存用户信息
- */
- void saveUser();
- }
第四步:然后找到UserServiceImpl 对方法进行重写 Ctrl+O
重写 调用userDao里面的saveUser();
第五步:UseDao接口里面创建方法 创建保存用户信息方法
- public interface UserDao {
-
- /**
- * 保存用户信息
- */
- void saveUser();
- }
第六步:找到Dao的实现类 进行方法重写
- @Repository
- public class UserDaoImpl implements UserDao {
-
-
- @Override
- public void saveUser() {
- System.out.println("保存成功");
- }
- }
第一步:在UserController中声明UserService对象
在UserServiceImpl中声明UserDao对象
第二步:在UserController里面 userService对象调用方法saveUser(); 调用保存用户信息方法
第三步:UserService接口里面创建方法 创建保存用户信息方法
第四步:然后找到UserServiceImpl 对方法进行重写 Ctrl+O
第五步:UseDao接口里面创建方法 创建保存用户信息方法
第六步:找到Dao的实现类 进行方法重写
问题:如何实现自动装配的效果
UserController
- @Controller
- public class UserController {
- @Autowired
- private UserService userService;
-
-
- public void saveUser(){
- userService.saveUser();
- }
- }
UserServiceImpl
- @Service
- public class UserServiceImpl implements UserService {
-
- @Autowired
- private UserDao userDao;
-
- @Override
- public void saveUser() {
- userDao.saveUser();
- }
- }
测试:
- public class IOCByAnnotationTest {
-
- /**
- * @Component:将类标识为普通组件
- * @Controller:将类标识为控制层组件
- * @Service:将类标识为业务层组件
- * @Repository:将类标识为持久层组件
- *
- * 通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名的首字母为小写的结果
- * 可以通过标识组件的注解的value属性值设置bean的自定义的id
- *
- * @Autowired:实现自动装配功能的注解
- * 1、@Autowired注解能够标识的位置
- * a>标识在成员变量上,此时不需要设置成员变量的set方法
- * b>标识在set方法上
- * c>标识在为当前成员变量赋值的有参构造上
- * 2、@Autowired注解的原理
- * a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
- * b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果
- * 即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
- * c>若byType和byName的方式都无妨实现自动装配,即IOC容器中有多个类型匹配的bean
- * 且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常:NoUniqueBeanDefinitionException
- * d>此时可以在要赋值的属性上,添加一个注解@Qualifier
- * 通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值
- *
- * 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException
- * 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配
- * 可以将required设置为false,此时能装配则装配,无法装配则使用属性的默认值
- */
-
- @Test
- public void test(){
- ApplicationContext ioc =new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
-
- // UserController userController = ioc.getBean("controller",UserController.class);
- UserController userController = ioc.getBean("userController",UserController.class);
- /* System.out.println(userController);
- UserService userService = ioc.getBean("userServiceImpl",UserService.class);
- System.out.println(userService);
- UserDao userDao = ioc.getBean("userDaoImpl",UserDao.class);
- System.out.println(userDao);*/
- userController.saveUser();
- }
- }
保存成功说明UserController里面的userService已经被赋值,UserServiceImpl里面的userDao也被赋值了
总结:加了自动装配@Autowired注解后,UserController里面的userService和UserServiceImpl里面的userDao被赋值
@Autowired注解也可以标记在构造器和set方法上
@Autowired注解标记在set方法上
- @Controller
- public class UserController {
-
- private UserService userService;
-
- @Autowired
- public void setUserService(UserService userService) {
- this.userService = userService;
- }
-
- public void saveUser(){
- userService.saveUser();
- }
- }
@Autowired注解标记在有参构造器上
- //@Controller("controller")
- @Controller
- public class UserController {
-
- private UserService userService;
-
- @Autowired
- public UserController(UserService userService) {
- this.userService = userService;
- }
-
-
- /* public void setUserService(UserService userService) {
- this.userService = userService;
- }*/
-
- public void saveUser(){
- userService.saveUser();
- }
- }
@Autowired注解的原理 * a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值 byType:根据类型在ioc容器中找到一个和类型匹配的bean来为当前的属性自动进行赋值 byName:把我们要赋值的属性的属性名,做为bean的id在IOC容器上去匹配到某一个bean来为当前的属性赋值 * b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果 * 即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
先前的bean
通过注解在扫描 在ioc容器中已经有UserServiceImpl一个bean
下面在加二个bean
- "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">
-
-
-
-
-
-
-
- <context:component-scan base-package="com.atguigu.spring">context:component-scan>
-
- <bean id="userService" class="com.atguigu.spring.service.impl.UserServiceImpl">bean>
-
- <bean id="userDao" class="com.atguigu.spring.dao.impl.UserDaoImpl">bean>
-
- beans>
解释:
在UserController里面要赋值叫做userService 而在xml里面也设置了一个bean也叫做userService
在UserServiceImpl里面使用了一个userDao,在xml里面也设置了一个bean也叫做userDao
所以这里是自动转化为byName的方式实现自动装配的效果
* c>若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean * 且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常:NoUniqueBeanDefinitionException*
- "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">
-
-
-
-
-
-
-
- <context:component-scan base-package="com.atguigu.spring">context:component-scan>
-
-
- <bean id="service" class="com.atguigu.spring.service.impl.UserServiceImpl">bean>
-
- <bean id="dao" class="com.atguigu.spring.dao.impl.UserDaoImpl">bean>
-
-
- beans>
报错: Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.atguigu.spring.service.UserService' available: expected single matching bean but found 2: userServiceImpl,service * d>此时可以在要赋值的属性上,添加一个注解@Qualifier * 通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值 解决办法
- @Controller
- public class UserController {
-
- @Autowired
- @Qualifier("userServiceImpl")
- private UserService userService;
-
-
- /* public UserController(UserService userService) {
- this.userService = userService;
- }*/
-
-
- /* public void setUserService(UserService userService) {
- this.userService = userService;
- }*/
-
- public void saveUser(){
- userService.saveUser();
- }
- }
- @Service
- public class UserServiceImpl implements UserService {
-
- @Autowired
- @Qualifier("userDaoImpl")
- private UserDao userDao;
-
- @Override
- public void saveUser() {
- userDao.saveUser();
- }
- }
注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException 忘记写@Service
- public class UserServiceImpl implements UserService {
-
- @Autowired
- // @Qualifier("userDaoImpl")
- private UserDao userDao;
-
- @Override
- public void saveUser() {
- userDao.saveUser();
- }
- }
报错 Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atguigu.spring.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 没有一个UserService所匹配的bean 此时就要找到UserService的实现加上@Service * 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配 * 可以将required设置为false,此时能装配则装配,无法装配则使用属性的默认值
总结:
/** * @Component:将类标识为普通组件 * @Controller:将类标识为控制层组件 * @Service:将类标识为业务层组件 * @Repository:将类标识为持久层组件 * * 通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名的首字母为小写的结果 * 可以通过标识组件的注解的value属性值设置bean的自定义的id * * @Autowired:实现自动装配功能的注解 * 1、@Autowired注解能够标识的位置 * a>标识在成员变量上,此时不需要设置成员变量的set方法 * b>标识在set方法上 * c>标识在为当前成员变量赋值的有参构造上 * 2、@Autowired注解的原理 * a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值 * b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果 * 即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值 * c>若byType和byName的方式都无妨实现自动装配,即IOC容器中有多个类型匹配的bean * 且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常:NoUniqueBeanDefinitionException * d>此时可以在要赋值的属性上,添加一个注解@Qualifier * 通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值 * * 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException * 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配 * 可以将required设置为false,此时能装配则装配,无法装配则使用属性的默认值 */