Appearance
@[toc]
一、Spring5概述与快速入门
1、Spring概述
1、简介
Spring框架是一个开放源代码的J2EE应用程序框架,由[Rod Johnson](https://baike.baidu.com/item/Rod Johnson/1423612)发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于J2EE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
- Spring 是
轻量级
的开源的 JavaEE 框架 - Spring 可以解决企业应用开发的复杂性
- Spring 有两个核心部分:
IOC
和AOP
IOC:控制反转
,把创建对象过程交给 Spring 进行管理AOP:面向切面
,不修改源代码进行功能增强
- Spring 特点
- 方便解耦,简化开发
- AOP 编程支持
- 方便程序测试
- 方便和其他框架进行整合
- 方便进行事务操作
- 降低 API 开发难度
2、官网
2、IOC容器
1、IOC概念和原理
概念:
- 控制反转,把对象创建和对象的调用过程交给spring进行管理。
- 目的:降低耦合度。
- 底层原理:xml,反射,工厂模式
- Spring提供IOC容器两种实现方式(两个接口)
- BeanFactory:Spring内部使用的接口,不提倡开发人员使用。特点:加载配置文件时不会创建对象,获取对象时才会创建对象。
- ApplicationContext:BeanFactory的子接口,提供了更多更强大的功能,一般由开发人员使用。特点:加载配置文件时会把配置文件里的对象进行创建。
- ApplicationContext两个常用实现类:
- FileSystemXmlApplicationContext:绝对路径,从盘符开始算起
- ClassPathXmlApplicationContext:相对路径,从
src
开始算起
什么是Bean管理?Bean管理是指两个操作:Spring创建对象
和 Spring注入属性
Bean管理有两种操作方式:基于xml配置文件
方式实现 和 基于注解
方式实现
3、IDEA创建Maven工程
1、导入依赖
xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.18</version>
</dependency>
为了后续开发方便 导入 lombok
插件
xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
4、IOC操作Bean管理(基于xml)
- 在Spring配置文件中使用
bean
标签来创建对象 - bean标签有很多属性,常用属性:
- id:唯一标识
- class:类路径
- 创建对象时,默认执行无参构造函数
1、创建User类
java
package com.xue.model;
import lombok.Data;
/**
* @Author: xueqimiao
* @Date: 2022/7/1 22:45
*/
@Data
public class User {
private String name;
private Integer age;
}
2、创建Spring配置文件
将User对象放入Spring容器
bean01.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置User对象 -->
<bean id="user" class="com.xue.model.User"></bean>
</beans>
3、编写测试类进行测试
需要加入junit
依赖
xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>compile</scope>
</dependency>
java
@Test
public void test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
// 根据类型获取
User user = context.getBean(User.class);
System.out.println(user);
}
java
User(name=null, age=null)
4、基于xml方式给属性赋值
1、使用set方法进行注入
由于我们在实体类上标注了 @Data
注解,会自动生成get、set
方法
xml
<!-- 配置User对象 -->
<bean id="user" class="com.xue.model.User">
<property name="name" value="xue"></property>
<property name="age" value="18"></property>
</bean>
再次运行测试类
java
User(name=xue, age=18)
2、使用有参构造函数进行注入
java
// 在User类加入构造方法
public User(){}
public User(String name, Integer age){
this.name = name;
this.age = age;
}
修改 xml
为
xml
<bean id="user" class="com.xue.model.User">
<constructor-arg name="name" value="xue"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
3、使用 P 名称空间注入(不重要,了解)
加入 P 名称空间
xml
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.xue.model.User" p:name="xue2" p:age="19"></bean>
</beans>
5、xml注入其他特殊属性
1、null值
xml
<bean id="user" class="com.xue.model.User">
<property name="name"> <null/></property>
<property name="age" value="18"></property>
</bean>
2、属性值包含特殊符号
假设现在name
属性需要赋值为 < xue >
如果像上面那样直接在value中声明的话会报错,因为包含特殊符号 <>
把<>进行转义 <> 把带特殊符号内容写到CDATA,用 <![CDATA[值]]>
来表示
xml
<bean id="user" class="com.xue.model.User">
<property name="name"><value><![CDATA[<xue>]]></value></property>
<property name="age" value="18"></property>
</bean>
3、注入外部bean
创建UserService
、UserDao
和UserDaoImpl
,其中UserDaoImpl
实现UserDao
接口
java
package com.xue.dao;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:22
*/
public interface UserDao {
}
java
package com.xue.dao.impl;
import com.xue.dao.UserDao;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:25
*/
public class UserDaoImpl implements UserDao {
}
java
package com.xue.service;
import com.xue.dao.UserDao;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:22
*/
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public UserDao getUserDao(){
return userDao;
}
public void add(){
System.out.println("add");
}
}
通过 ref
来指定创建userDaoImpl
xml
<bean id="userDaoImpl" class="com.xue.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.xue.service.UserService">
<property name="userDao" ref="userDaoImpl"></property>
</bean>
编写测试类
java
@Test
public void test02(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
// 根据类型获取
UserService userService = context.getBean(UserService.class);
System.out.println(userService.getUserDao());
}
4、注入内部bean
不通过ref属性,而是通过嵌套一个bean标签实现
新建Dept
和Emp
类
java
package com.xue.model;
import lombok.Data;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:30
*/
@Data
public class Dept {
private String deptName;
}
java
package com.xue.model;
import lombok.Data;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:31
*/
@Data
public class Emp {
private String empName;
private Dept dept;
}
xml
<bean id="emp" class="com.xue.model.Emp">
<!--设置普通属性-->
<property name="empName" value="张三"></property>
<!--设置对象类型属性-->
<property name="dept">
<bean id="dept" class="com.xue.model.Dept">
<property name="deptName" value="开发部"></property>
</bean>
</property>
</bean>
编写测试类
java
@Test
public void test03(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
// 根据类型获取
Emp emp = context.getBean(Emp.class);
System.out.println(emp.getEmpName());
System.out.println(emp.getDept());
System.out.println(emp.getDept().getDeptName());
}
5、注入级联属性
写法一、通过ref属性来获取外部bean
xml
<bean id="emp" class="com.xue.model.Emp">
<!--设置普通属性-->
<property name="empName" value="张三"></property>
<!--设置对象类型属性-->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.xue.model.Dept">
<property name="deptName" value="开发部"></property>
</bean>
写法二、需要emp提供dept属性的get方法
xml
<bean id="emp" class="com.xue.model.Emp">
<!--设置普通属性-->
<property name="empName" value="张三"></property>
<!--设置对象类型属性-->
<property name="dept" ref="dept"></property>
<property name="dept.deptName" value="技术部"></property>
</bean>
<bean id="dept" class="com.xue.model.Dept">
</bean>
6、注入集合属性
创建 Student
类
java
package com.xue.model;
import lombok.Data;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:41
*/
@Data
public class Student {
/**
* 数组类型属性
*/
private String[] courses;
/**
* list集合类型属性
*/
private List<String> list;
/**
* map集合类型属性
*/
private Map<String, String> maps;
/**
* set集合类型属性
*/
private Set<String> sets;
}
在xml配置文件中对这些集合属性进行注入
xml
<bean id="stu" class="com.xue.model.Student">
<!--数组类型属性注入-->
<property name="courses">
<array>
<value>java课程</value>
<value>数据库课程</value>
</array>
</property>
<!--List类型属性注入-->
<property name="list">
<list>
<value>张三</value>
<value>李四</value>
</list>
</property>
<!--Map类型属性注入-->
<property name="maps">
<map>
<entry key="JAVA" value="java"></entry>
<entry key="PHP" value="php"></entry>
</map>
</property>
<!--Set类型属性注入-->
<property name="sets">
<set>
<value>Mysql</value>
<value>Redis</value>
</set>
</property>
</bean>
编写测试类
java
@Test
public void test04(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
// 根据类型获取
Student student = context.getBean(Student.class);
System.out.println(student.getCourses());
System.out.println(student.getList());
System.out.println(student.getMaps());
System.out.println(student.getSets());
}
7、注入集合对象属性
新建Course
和Student2
类
java
package com.xue.model;
import lombok.Data;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:46
*/
@Data
public class Course {
private String courseName;
}
java
package com.xue.model;
import lombok.Data;
import java.util.List;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:46
*/
@Data
public class Student2 {
private List<Course> courseList;
}
xml
<!--创建多个 course 对象-->
<bean id="course1" class="com.xue.model.Course">
<property name="courseName" value="Spring5 框架"></property>
</bean>
<bean id="course2" class="com.xue.model.Course">
<property name="courseName" value="MyBatis 框架"></property>
</bean>
<bean id="student2" class="com.xue.model.Student2">
<!--注入 list 集合类型,值是对象-->
<property name="courseList">
<list>
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
编写测试类
java
@Test
public void test05(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
// 根据类型获取
Student2 student = context.getBean(Student2.class);
List<Course> courseList = student.getCourseList();
courseList.forEach(course -> {
System.out.println(course.getCourseName());
});
}
把集合注入部分提取出来
在 spring 配置文件中引入名称空间 util
xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
</beans>
xml
<!--创建多个 course 对象-->
<bean id="course1" class="com.xue.model.Course">
<property name="courseName" value="Spring5 框架"></property>
</bean>
<bean id="course2" class="com.xue.model.Course">
<property name="courseName" value="MyBatis 框架"></property>
</bean>
<bean id="student2" class="com.xue.model.Student2">
<!--注入 list 集合类型,值是对象-->
<property name="courseList" ref="courseList"></property>
</bean>
<util:list id="courseList">
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</util:list>
6、IOC操作Bean管理(FactoryBean)
- Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean (FactoryBean)
- 普通 bean:在配置文件中定义 bean 类型就是返回类型
- 工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
- 第一步 创建类, 让这个类作为工厂 bean,实现接口 FactoryBean
- 第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
java
package com.xue.bean;
import com.xue.model.Course;
import org.springframework.beans.factory.FactoryBean;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 15:22
*/
public class MyBean implements FactoryBean<Course> {
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCourseName("Spring5");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
新建bean02.xml
xml
<bean id="myBean" class="com.xue.bean.MyBean"></bean>
java
@Test
public void test06(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean02.xml");
// 根据类型获取
Course course = context.getBean("myBean",Course.class);
System.out.println(course);
}
7、Bean的作用域
在Spring中,默认情况下bean是单实例
对象
创建bean03.xml
xml
<bean id="course" class="com.xue.model.Course">
<property name="courseName" value="Spring5 框架"></property>
</bean>
java
@Test
public void test07(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
// 根据类型获取
Course course1 = context.getBean(Course.class);
Course course2 = context.getBean(Course.class);
// true
System.out.println(course1 == course2);
}
通过 bean标签的scope
属性 来设置单实例还是多实例
singleton
:默认值,表示单实例对象。加载配置文件时就会创建单实例对象。prototype
:表示多实例对象。不是在加载配置文件时创建对象,在调用getBean方法时创建多实例对象。
xml
<bean id="course" class="com.xue.model.Course" scope="prototype">
<property name="courseName" value="Spring5 框架"></property>
</bean>
java
@Test
public void test07(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
// 根据类型获取
Course course1 = context.getBean(Course.class);
Course course2 = context.getBean(Course.class);
// false
System.out.println(course1 == course2);
}
8、bean的生命周期(入门)
- 通过构造器创建 bean 实例(无参数构造)
- 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
- 调用 bean 的初始化的方法(需要进行配置初始化的方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
- bean 可以使用了(对象获取到了)
- 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
演示一下
java
package com.xue.bean;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 15:37
*/
public class Orders {
private String orderName;
public Orders() {
System.out.println("第一步:执行无参构造方法创建bean实例");
}
public void setOrderName(String orderName) {
this.orderName = orderName;
System.out.println("第二步:调用set方法设置属性值");
}
/**
* 初始化方法
*/
public void initMethod(){
System.out.println("第三步:执行初始化方法");
}
/**
* 销毁方法
*/
public void destroyMethod(){
System.out.println("第五步:执行销毁方法");
}
}
xml
<bean id="orders" class="com.xue.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
<property name="orderName" value="手机"></property>
</bean>
java
@Test
public void test08(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean03.xml");
// 根据类型获取
Orders orders = context.getBean(Orders.class);
System.out.println("第四步 获取创建 bean 实例对象");
System.out.println(orders);
//手动让bean实例销毁
context.close();
}
第一步:执行无参构造方法创建bean实例
第二步:调用set方法设置属性值
第三步:执行初始化方法
第四步 获取创建 bean 实例对象
com.xue.bean.Orders@706a04ae
第五步:执行销毁方法
bean 的后置处理器
, bean生命周期有七步
- 通过构造器创建 bean 实例(无参数构造)
- 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
- 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
- 调用 bean 的初始化的方法(需要进行配置初始化的方法
- 把bean实例传递 bean后置处理器的方法 postProcessAfterInitialization
- bean 可以使用了(对象获取到了)
- 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
java
package com.xue.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 15:38
*/
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之前执行的方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之后执行的方法");
return bean;
}
}
xml
<!--配置后置处理器-->
<bean id="myBeanPost" class="com.xue.bean.MyBeanPost"></bean>
第一步:执行无参构造方法创建bean实例
第二步:调用set方法设置属性值
在初始化之前执行的方法
第三步:执行初始化方法
在初始化之后执行的方法
第四步 获取创建 bean 实例对象
com.xue.bean.Orders@706a04ae
第五步:执行销毁方法
9、xml自动装配
根据指定装配规则(属性名称或者属性类型), Spring 自动将匹配的属性值进行注入
新建bean04.xml
- 根据指定的装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
- 根据属性名称自动装配:要求 emp中属性的名称dept 和 bean标签的id值dept 一样,才能识别
xml
<bean id="emp" class="com.xue.model.Emp" autowire="byName"></bean>
<bean id="dept" class="com.xue.model.Dept">
<property name="deptName" value="研发部"></property>
</bean>
java
@Test
public void test09(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean04.xml");
// 根据类型获取
Emp emp = context.getBean(Emp.class);
System.out.println(emp);
System.out.println(emp.getDept());
}
根据属性类型自动装配:要求同一个xml文件中不能有两个相同类型的bean,否则无法识别是哪一个
xml
<bean id="emp" class="com.xue.model.Emp" autowire="byType"></bean>
<bean id="dept" class="com.xue.model.Dept">
<property name="deptName" value="研发部"></property>
</bean>
10、通过外部属性文件来操作bean
例如配置数据库信息:
导入
druid
连接池jar包创建外部属性文件,properties格式文件,写数据库信息
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
创建外部属性文件, properties
格式文件, 写数据库信息
jdbc.properties
properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test01
userName=root
password=root
把外部 properties 属性文件引入到 spring 配置文件中
引入 context 名称空间
xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
xml
<!--引入外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClass}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${userName}"></property>
<property name="password" value="${password}"></property>
</bean>
5、IOC操作Bean管理(基于注解)
- 格式:@注解名称(属性名=属性值,属性名=属性值,……)
- 注解可以作用在类,属性,方法。
- 使用注解的目的:简化xml配置
Spring 针对Bean管理中创建对象提供注解
@Component
@Service
@Controller
@Repository
上面四个注解功能是一样的, 都可以用来创建 bean 实例
引入依赖
xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.18</version>
</dependency>
开启组件扫描
如果扫描多个包,多个包使用逗号隔开
新建bean05.xml
xml
<?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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
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/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.xue"></context:component-scan>
</beans>
创建类(由于类我们之前就创建了,这里加上注解即可), 在类上面添加创建对象注解
java
@Component("userDao")
public class UserDaoImpl implements UserDao {
}
java
package com.xue.service;
import com.xue.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:22
*/
@Service("userService")
public class UserService {
@Autowired
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public UserDao getUserDao(){
return userDao;
}
public void add(){
System.out.println("add");
}
}
java
@Test
public void test10(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean05.xml");
// 根据类型获取
UserService userService = context.getBean(UserService.class);
System.out.println(userService.getUserDao());
}
开启组件扫描的细节配置
use-default-fileters设置为false表示不使用默认过滤器,通过include-filter来设置只扫描com.oymn包下的所有@Controller修饰的类。
XML
<context:component-scan base-package="com.xue" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
exclude-filter设置哪些注解不被扫描,例子中为@Controller修饰的类不被扫描
XML
<context:component-scan base-package="com.xue">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
1、基于注解进行属性注入
@Autowired:根据属性类型自动装配
我们在上面的UserService
中已经用过了
@Qualifier:根据名称进行注入
这个@Qualifier 注解的使用,和上面@Autowired 一起使用
当遇到一个接口有很多实现类时,只通过@Autowire是无法完成自动装配的,所以需要再使用@Qualifier通过名称来锁定某个类
在新建一个 UserDaoImpl2
java
package com.xue.dao.impl;
import com.xue.dao.UserDao;
import org.springframework.stereotype.Component;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 14:25
*/
@Component("userDao2")
public class UserDaoImpl2 implements UserDao {
}
此时以下这种写法
@Autowired优先采用的是根据类型注入,如果有多个类型一样的组件,会根据属性名称进行注入,所以下面会通过属性名称注入
java
@Autowired
private UserDao userDao;
如果我们想注入userDao2
java
@Autowired
@Qualifier("userDao2")
private UserDao userDao;
@Resource:可以根据类型注入,也可以根据名称注入(默认根据名称注入)
2、注解扫包
新建配置类
java
package com.xue.config;
import com.xue.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Author: xueqimiao
* @Date: 2022/7/2 16:09
* 这个配置类也是一个组件
* 告诉Spring这是一个配置类
*/
@Configuration
@ComponentScan(basePackages = {"com.xue"})
public class Config01 {
}
java
@Test
public void test11(){
//创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config01.class);
UserService userService = context.getBean(UserService.class);
System.out.println(userService.getUserDao());
}