一、Spring5概述与快速入门

一、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。

  1. Spring 是轻量级的开源的 JavaEE 框架
  2. Spring 可以解决企业应用开发的复杂性
  3. Spring 有两个核心部分:IOC 和 Aop
    1. IOC:控制反转,把创建对象过程交给 Spring 进行管理
    2. Aop:面向切面,不修改源代码进行功能增强
  4. Spring 特点
    1. 方便解耦,简化开发
    2. Aop 编程支持
    3. 方便程序测试
    4. 方便和其他框架进行整合
    5. 方便进行事务操作
    6. 降低 API 开发难度

2、官网

https://spring.io/

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、导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.18</version>
</dependency>

为了后续开发方便 导入 lombok插件

<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类

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 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依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>compile</scope>
</dependency>
@Test
public void test01(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean01.xml");
    // 根据类型获取
    User user = context.getBean(User.class);
    System.out.println(user);
}
User(name=null, age=null)

4、基于xml方式给属性赋值

1、使用set方法进行注入

由于我们在实体类上标注了 @Data 注解,会自动生成get、set方法

<!-- 配置User对象 -->
<bean id="user" class="com.xue.model.User">
    <property name="name" value="xue"></property>
    <property name="age" value="18"></property>
</bean>

再次运行测试类

User(name=xue, age=18)
2、使用有参构造函数进行注入
// 在User类加入构造方法
public User(){}
    
public User(String name, Integer age){
    this.name = name;
    this.age = age;
}

修改 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 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值
<bean id="user" class="com.xue.model.User">
    <property name="name"> <null/></property>
    <property name="age" value="18"></property>
</bean>
2、属性值包含特殊符号

假设现在name属性需要赋值为 < xue >

如果像上面那样直接在value中声明的话会报错,因为包含特殊符号 <>

把<>进行转义 &lt;&gt;
把带特殊符号内容写到CDATA,用 <![CDATA[值]]> 来表示

<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

创建UserServiceUserDaoUserDaoImpl,其中UserDaoImpl实现UserDao接口

package com.xue.dao;

/**
 * @Author: xueqimiao
 * @Date: 2022/7/2 14:22
 */
public interface UserDao {
}
package com.xue.dao.impl;

import com.xue.dao.UserDao;

/**
 * @Author: xueqimiao
 * @Date: 2022/7/2 14:25
 */
public class UserDaoImpl implements UserDao {
}

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

<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>

编写测试类

@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标签实现

新建DeptEmp

package com.xue.model;

import lombok.Data;

/**
 * @Author: xueqimiao
 * @Date: 2022/7/2 14:30
 */
@Data
public class Dept {
    
    private String deptName;
    
}
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;
}
<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>

编写测试类

@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

<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方法

<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

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配置文件中对这些集合属性进行注入

<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>

编写测试类

@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、注入集合对象属性

新建CourseStudent2

package com.xue.model;

import lombok.Data;

/**
 * @Author: xueqimiao
 * @Date: 2022/7/2 14:46
 */
@Data
public class Course {
    
    private String courseName;
}
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;
}
<!--创建多个 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>

编写测试类

@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 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>
<!--创建多个 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)

  1. Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean (FactoryBean)
  2. 普通 bean:在配置文件中定义 bean 类型就是返回类型
  3. 工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
    1. 第一步 创建类, 让这个类作为工厂 bean,实现接口 FactoryBean
    2. 第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
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

<bean id="myBean" class="com.xue.bean.MyBean"></bean>
@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

<bean id="course" class="com.xue.model.Course">
    <property name="courseName" value="Spring5 框架"></property>
</bean>
@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方法时创建多实例对象。
<bean id="course" class="com.xue.model.Course" scope="prototype">
    <property name="courseName" value="Spring5 框架"></property>
</bean>
@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的生命周期(入门)

  1. 通过构造器创建 bean 实例(无参数构造)
  2. 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
  3. 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
  4. 调用 bean 的初始化的方法(需要进行配置初始化的方法)
  5. 把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
  6. bean 可以使用了(对象获取到了)
  7. 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

演示一下

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("第五步:执行销毁方法");
    }
}
<bean id="orders" class="com.xue.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
    <property name="orderName" value="手机"></property>
</bean>
@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生命周期有七步

  1. 通过构造器创建 bean 实例(无参数构造)
  2. 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
  3. 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
  4. 调用 bean 的初始化的方法(需要进行配置初始化的方法
  5. 把bean实例传递 bean后置处理器的方法 postProcessAfterInitialization
  6. bean 可以使用了(对象获取到了)
  7. 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
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;
    }
}
<!--配置后置处理器-->
<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 一样,才能识别
<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>
@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,否则无法识别是哪一个

<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

例如配置数据库信息:

  1. 导入druid连接池jar包

  2. 创建外部属性文件,properties格式文件,写数据库信息

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
</dependency>

创建外部属性文件, properties 格式文件, 写数据库信息

jdbc.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test01
userName=root
password=root

把外部 properties 属性文件引入到 spring 配置文件中

引入 context 名称空间

<?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>
<!--引入外部属性文件-->
<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 实例

引入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.18</version>
</dependency>

开启组件扫描

如果扫描多个包,多个包使用逗号隔开

新建bean05.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>

创建类(由于类我们之前就创建了,这里加上注解即可), 在类上面添加创建对象注解

@Component("userDao")
public class UserDaoImpl implements UserDao {
}
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");
    }
}

@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修饰的类。

<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修饰的类不被扫描

<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

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优先采用的是根据类型注入,如果有多个类型一样的组件,会根据属性名称进行注入,所以下面会通过属性名称注入

@Autowired
private UserDao userDao;

如果我们想注入userDao2

@Autowired
@Qualifier("userDao2")
private UserDao userDao;

@Resource:可以根据类型注入,也可以根据名称注入(默认根据名称注入)

2、注解扫包

新建配置类

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 {
    
}
@Test
public void test11(){
    //创建AnnotationConfigApplicationContext对象
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config01.class);
    UserService userService = context.getBean(UserService.class);
    System.out.println(userService.getUserDao());
}

更多注解开发请见后面章节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小薛博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值