Spring:(二)IOC

2.1 IOC简介

IOC:控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理 ;使用 IOC 目的是为了降低代码耦合度;IOC的底层原理是XML解析+工厂模式+反射。(详细了解IOC底层请见JavaWeb:(十一)DI/IOC,手撕IOC底层代码)

2.2 IOC容器

IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂。Spring 提供 IOC 容器实现两种方式:

  1. BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用 ,加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
  2. ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人 员进行使用 ,加载配置文件时候就会把在配置文件对象进行创建

2.3 xml方式Bean管理

2.3.1 什么是Bean管理

Bean 管理指的是两个操作

  1. Spring 创建对象
  2. Spirng 注入属性

Bean 管理操作有两种方式

  1. 基于 xml 配置文件方式实现
  2. 基于注解方式实现(注解只是通过Spring自动帮我们配置Bean,XML则是手动进行配置,但二者本质上是一样的)

2.3.2 xml方式创建对象

在 spring 配置文件中,使用标签,标签里面添加对应属性,就可以实现对象创建;bean标签有两个主要的属性:

  • id 属性:唯一标识
  • class 属性:类全路径(包类路径)

创建对象时候,默认也是执行无参数构造方法完成对象创建,所以Java类都要事先无参构造函数

2.3.3 xml方式注入属性

DI:依赖注入,就是为Bean注入依赖,即注入属性,Spring提供了多种注入方式:

  • 第一种注入方式:使用 set 方法进行注入

    1. 创建类,定义属性和对应的 set 方法

      public class Book {
          private String bookName;
          private String bookAuthor;
      
          public void setBookName(String bookName) {
              this.bookName = bookName;
          }
      
          public void setBookAuthor(String bookAuthor) {
              this.bookAuthor = bookAuthor;
          }
          
          @Override
          public String toString() {
              return "Book{" +
                      "bookName='" + bookName + '\'' +
                      ", bookAuthor='" + bookAuthor + '\'' +
                      '}';
          }
      }
      
    2. 在 spring 配置文件配置对象创建,配置属性注入

      <?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">
          <bean id="book" class="pojo.Book">
              <property name="bookName" value="天龙八部"></property>
              <property name="bookAuthor" value="金庸"></property>
          </bean>
      </beans>
      
    3. 测试代码

      public class Test1 {
          @Test
          public void test(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
              Book book = context.getBean("book", Book.class);
              System.out.println(book);
          }
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lezdGEXk-1658593714080)(../../AppData/Roaming/Typora/typora-user-images/image-20220723025003753.png)]

  • 第二种注入方式:使用有参数构造进行注入

    1. 创建类,定义属性,创建属性对应有参数构造方法

      public class Book {
          private String bookName;
          private String bookAuthor;
      
          public Book(String bookName, String bookAuthor) {
              this.bookName = bookName;
              this.bookAuthor = bookAuthor;
          }
      
          @Override
          public String toString() {
              return "Book{" +
                      "bookName='" + bookName + '\'' +
                      ", bookAuthor='" + bookAuthor + '\'' +
                      '}';
          }
      }
      
    2. 在 spring 配置文件中进行配置

      <?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">
          <bean id="book" class="pojo.Book">
              <constructor-arg name="bookName" value="天涯明月刀"></constructor-arg>
              <constructor-arg name="bookAuthor" value="古龙"></constructor-arg>
          </bean>
      </beans>
      
    3. 测试代码

      public class Test1 {
          @Test
          public void test(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
              Book book = context.getBean("book", Book.class);
              System.out.println(book);
          }
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ySZKct31-1658593714082)(https://s2.loli.net/2022/07/23/tOXc9yoE82ljQbG.png)]

  • 第三种注入方式:p名称空间注入

    1. 添加 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">
      </beans>
      
    2. 进行属性注入,在 bean 标签里面进行操作(本质上还是set注入,需要提供set方法)

      <?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="book" class="pojo.Book" p:bookName="白发魔女传" p:bookAuthor="梁羽生"></bean>
      </beans>
      
    3. 测试代码

      public class Test1 {
          @Test
          public void test(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
              Book book = context.getBean("book", Book.class);
              System.out.println(book);
          }
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dSGkrayo-1658593714082)(../../AppData/Roaming/Typora/typora-user-images/image-20220723031041277.png)]

2.3.4 xml注入各种类型的属性

  1. 注入null值

    <?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="book" class="pojo.Book">
            <property name="bookName">
                <null/>
            </property>
            <property name="bookAuthor" value="无中生有的作者"></property>
        </bean>
    </beans>
    
    public class Test1 {
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            Book book = context.getBean("book", Book.class);
            System.out.println(book);
        }
    }
    

    image-20220723161808998

  2. 注入带特殊符号的属性值

    <?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">
        <bean id="book" class="pojo.Book">
            <!--属性值包含特殊符号
             1 把<>进行转义 &lt; &gt;
             2 把带特殊符号内容写到 CDATA
            -->
            <property name="bookName">
                <value><![CDATA[<<斗破苍穹>>]]></value>
            </property>
            <property name="bookAuthor" value="天蚕土豆"></property>
        </bean>
    </beans>
    

    image-20220723162113884

  3. 注入外部bean

    • 创建两个类 service 类和 dao 类,在 service 调用 dao 里面的方法

      public interface UserDAO {
          public void update() ;
      }
      
      public class UserDAOImpl implements UserDAO {
          @Override
          public void update() {
              System.out.println("执行UserDAO的update方法...");
          }
      }
      
      public class UserService {
          //创建 UserDao 类型属性,生成 set 方法
          private UserDAO userDao;
          public void setUserDao(UserDAO userDao) {
              this.userDao = userDao;
          }
          public void update() {
              System.out.println("执行UserService的update方法");
              userDao.update();
          }
      }
      
    • 在 spring 配置文件中进行配置

      <?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">
          <bean id="userDAO" class="dao.impl.UserDAOImpl"></bean>
      
          <bean id="userService" class="service.UserService">
              <property name="userDao" ref="userDAO"></property>
          </bean>
      </beans>
      
    • 代码测试

      public class Test1 {
          @Test
          public void test(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
              UserService userService = context.getBean("userService", UserService.class);
              userService.update();
          }
      }
      

      image-20220723165412193

  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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="userService" class="service.UserService">
            <property name="userDao">
                <bean id="userDAO" class="dao.impl.UserDAOImpl"></bean>
            </property>
        </bean>
    </beans>
    

    image-20220723165412193

  5. 级联赋值

    • 创建两个pojo类Dept和Employee

      public class Dept {
          private String deptName;
      
          public String getDeptName() {
              return deptName;
          }
      
          public void setDeptName(String deptName) {
              this.deptName = deptName;
          }
      
          @Override
          public String toString() {
              return "Dept{" + "deptName='" + deptName + '\'' + '}';
          }
      }
      
      public class Employee {
          private String employeeName;
          private String gender;
          private Dept dept;
      
          public void setEmployeeName(String employeeName) {
              this.employeeName = employeeName;
          }
      
          public void setGender(String gender) {
              this.gender = gender;
          }
      
          public void setDept(Dept dept) {
              this.dept = dept;
          }
      
          public Dept getDept() {
              return dept;
          }
      
          @Override
          public String toString() {
              return "Employee{" + "employeeName='" + employeeName + '\'' + 
                  ", gender='" + gender + '\'' + ", dept=" + dept + '}';
          }
      }
      
    • 在 spring 配置文件中进行配置

      <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">
          <bean id="employee" class="pojo.Employee">
              <property name="employeeName" value="张三"></property>
              <property name="gender" value=""></property>
              <property name="dept" ref="dept"></property>
              <property name="dept.deptName" value="技术部"></property>
          </bean>
      
          <bean id="dept" class="pojo.Dept"></bean>
      </beans>
      
    • 代码测试

      public class Test1 {
          @Test
          public void test(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
              Employee employee = context.getBean("employee", Employee.class);
              System.out.println(employee);
          }
      }
      

      image-20220723173957707

  6. 注入数组,list,set,map

    • 创建一个pojo类Student

      public class Student {
          //1 数组类型属性
          private String[] courses;
          //2 list 集合类型属性
          private List<String> list;
          //3 map 集合类型属性
          private Map<String,String> maps;
          //4 set 集合类型属性
          private Set<String> sets;
          public void setSets(Set<String> sets) {
              this.sets = sets;
          }
          public void setCourses(String[] courses) {
              this.courses = courses;
          }
          public void setList(List<String> list) {
              this.list = list;
          }
          public void setMaps(Map<String, String> maps) {
              this.maps = maps;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "\n\tcourses=" + Arrays.toString(courses) +
                      ", \n\tlist=" + list +
                      ", \n\tmaps=" + maps +
                      ", \n\tsets=" + sets +
                      "\n}";
          }
      }
      
    • 在 spring 配置文件进行配置

      <?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">
          <bean id="student" class="pojo.Student">
              <property name="courses">
                  <array>
                      <value>计算机网络</value>
                      <value>软件工程</value>
                      <value>数据结构</value>
                  </array>
              </property>
              <property name="list">
                  <list>
                      <value>大学语文</value>
                      <value>高等数学</value>
                      <value>大学物理</value>
                  </list>
              </property>
              <property name="sets">
                  <set>
                      <value>马克思主义原理</value>
                      <value>中国近代史纲要</value>
                      <value>毛泽东思想概论</value>
                  </set>
              </property>
              <property name="maps">
                  <map>
                      <entry key="第一门课" value="C++"></entry>
                      <entry key="第二门课" value="Java"></entry>
                      <entry key="第三门课" value="Python"></entry>
                  </map>
              </property>
          </bean>
      </beans>
      
    • 代码测试

      public class Test1 {
          @Test
          public void test(){
              ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
              Student student = context.getBean("student", Student.class);
              System.out.println(student);
          }
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zQ2Z1p3W-1658593714086)(https://s2.loli.net/2022/07/23/Z54SlaOnbyMHGcx.png)]

  7. 提取公共注入部分

    • 在 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: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">
      
    • 使用 util 标签完成 list 集合注入提取

      <util:list id="bookList">
          <value>大学语文</value>
          <value>高等数学</value>
          <value>大学物理</value>
      </util:list>
      
      <bean id="student" class="pojo.Student">
          <property name="list" ref="bookList"></property>
      </bean>
      

2.4.5 工厂Bean

Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)

  • 普通 bean:在配置文件中定义 bean 类型就是返回类型
  • 工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样

工厂Bean的创建方式:

  1. 创建类,让这个类作为工厂 bean,实现接口 FactoryBean

  2. 实现接口里面的方法,在实现的方法中定义返回的 bean 类型

    public class MyBean implements FactoryBean<Book> {
        //定义返回 bean
        @Override
        public Book getObject() throws Exception {
            Book book = new Book();
            book.setBookName("斗罗大陆");
            book.setBookAuthor("唐家三少");
            return book;
        }
        @Override
        public Class<?> getObjectType() {
            return null;
        }
        @Override
        public boolean isSingleton() {
            return false;
        }
    }
    
  3. 在 spring 配置文件进行配置

    <bean id="myBean" class="pojo.MyBean"></bean>
    
  4. 代码测试

    public class Test1 {
        @Test
        public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            Book book = context.getBean("myBean", Book.class);
            System.out.println(book);
        }
    }
    

    image-20220723205736571

2.3.6 Bean的作用域

在Spring里面,默认情况下,bean是单实例对象。在spring配置文件 bean 标签里面有属性scope用于设置单实例还是多实例:

  • singleton,表示是单实例对象,singleton是默认值。 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象。
  • prototype,表示是多实例对象。设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用 getBean 方法时候创建多实例对象。

2.3.7 Bean生命周期

七步版

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

八步版

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

代码演示(七步版)

  1. 编写一个pojo类,并在其中编写相应代码

    public class LifeCycle {
        private String lfName;
    
        public LifeCycle() {
            System.out.println("第一步 执行无参数构造创建 bean 实例");
        }
    
        public void setLfName(String lfName) {
            this.lfName = lfName;
            System.out.println("第二步 调用 set 方法设置属性值");
        }
    
        public void initMethod(){
            System.out.println("第四步 执行初始化的方法");
        }
    
        public void destroyMethod(){
            System.out.println("第七步 执行销毁的方法");
        }
    
        @Override
        public String toString() {
            return "LifeCycle{" + "lfName='" + lfName + '\'' + '}';
        }
    }
    
  2. 在 spring 配置文件进行配置

    <?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">
        <bean id="lifeCycle" class="pojo.LifeCycle" init-method="initMethod" destroy-method="destroyMethod">
            <property name="lfName" value="初始化lfName"></property>
        </bean>
        <!--配置后置处理器-->
        <bean id="myBeanPostProcessor" class="processor.MyBeanPostProcessor"></bean>
    </beans>
    
  3. 代码测试

    public class Test1 {
        @Test
        public void test(){
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            LifeCycle lifeCycle = context.getBean("lifeCycle", LifeCycle.class);
            System.out.println("第六步 获取创建 bean 实例对象:" + lifeCycle);
            context.close();
        }
    }
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3OGLXfSa-1658593714087)(../../AppData/Roaming/Typora/typora-user-images/image-20220723213313185.png)]

2.3.8 Bean自动装配(重点)

自动装配:根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入

实现自动装配 bean 标签属性 autowire,配置自动装配 autowire 属性常用两个值:

  • byName:根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
  • byType:根据属性类型注入

代码测试:

<?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">
    <bean id="employee" class="pojo.Employee" autowire="byName">
        <property name="gender" value=""></property>
        <property name="employeeName" value="李四"></property>
    </bean>
    <bean id="dept" class="pojo.Dept">
        <property name="deptName" value="英雄联盟分部"></property>
    </bean>
</beans>
public class Test1 {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Employee employee = context.getBean("employee", Employee.class);
        System.out.println(employee);
    }
}

image-20220723215042861

2.3.9 引入外部属性文件

  • 在Spring配置文件中直接配置Druid连接配置

    <?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">
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property>
            <property name="username" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
    </beans>
    
  • 引入外部属性文件配置数据库连接池

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

      image-20220723232812757

    2. 引入 context 名称空间,并把外部 properties 属性文件引入到 spring 配置文件中

      <?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 http://www.springframework.org/schema/context/spring-context.xsd">
          <!--引入外部属性文件-->
          <context:property-placeholder location="classpath:druid.properties"/>
          <!--配置连接池-->
          <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
              <property name="driverClassName" value="${driverClassName}"></property>
              <property name="url" value="${url}"></property>
              <property name="username" value="${username}"></property>
              <property name="password" value="${password}"></property>
          </bean>
      </beans>
      

2.4 注解方式Bean管理

2.4.1 什么是注解

  1. 注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)
  2. 使用注解,注解作用在类上面,方法上面,属性上面
  3. 使用注解目的:通过Spring进行自动配置,跳过手动的xml配置

Spring 针对 Bean 管理中创建对象提供注解 :

  1. @Component
  2. @Service
  3. @Controller
  4. @Repository

上面四个注解功能是一样的,都可以用来创建 bean 实例,但约定大于配置,故每个注解应该用于固定层级上

2.4.2 基于注解方式实现对象的创建

  1. 第一步:引入spring-aop依赖

  2. 第二步:在xml中开启组件扫描,如果是完全注解开发则需要在配置类中开启组件扫描

    <!--开启组件扫描
     1 如果扫描多个包,多个包使用逗号隔开
     2 扫描包上层目录
    -->
    <context:component-scan base-package="com.atguigu"></context:component-scan>
    
  3. 第三步:创建类,在类上面添加创建对象注解

    // 在注解里面 value 属性值可以省略不写,
    // 默认值是类名称,首字母小写 UserService -- userServic
    @Component
    public class UserDAOImpl implements UserDAO {
        @Override
        public void update() {
            System.out.println("执行UserDAO的update方法...");
        }
    }
    

2.4.3 开启组件扫描细节配置

<!--示例 1
 use-default-filters="false" 表示现在不使用默认 filter,自己配置 filter
 context:include-filter: 设置扫描哪些内容
-->
<context:component-scan base-package="com.atguigu" use-defaultfilters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

<!--示例 2
 下面配置扫描包所有内容
 context:exclude-filter: 设置哪些内容不进行扫描
-->
<context:component-scan base-package="com.atguigu">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

2.4.4 基于注解方式实现属性注入

  • @Autowired:根据属性类型进行自动装配

    @Component(value = "userDAO")
    public class UserDAOImpl implements UserDAO {
        @Override
        public void update() {
            System.out.println("执行UserDAO的update方法...");
        }
    }
    
  • @Qualifier:根据名称进行注入

    这个@Qualifier 注解的使用,和上面@Autowired 一起使用

    @Service
    public class UserService implements UserDAO {
    
        @Autowired
        @Qualifier(value = "userDAO")
        private UserDAO userDAO;
    
        public void setUserDAOImpl(UserDAO userDAOImpl) {
            this.userDAO = userDAOImpl;
        }
    
        public void update() {
            System.out.println("执行UserService的update方法");
            userDAO.update();
        }
    }
    
  • @Resource:既可以根据类型注入,也可以根据名称注入

    @Service
    public class UserService implements UserDAO {
    
        @Resource
        private UserDAO userDAO;
    
        public void setUserDAOImpl(UserDAO userDAOImpl) {
            this.userDAO = userDAOImpl;
        }
    
        public void update() {
            System.out.println("执行UserService的update方法");
            userDAO.update();
        }
    }
    
  • @Value:注入普通类型属性

    @Component
    public class Book {
    
        @Value(value = "九把刀")
        private String bookName;
        @Value(value = "那些年我们一起追过的女孩")
        private String bookAuthor;
    
        public void setBookName(String bookName) {
            this.bookName = bookName;
        }
    
        public void setBookAuthor(String bookAuthor) {
            this.bookAuthor = bookAuthor;
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "bookName='" + bookName + '\'' +
                    ", bookAuthor='" + bookAuthor + '\'' +
                    '}';
        }
    }
    
    public class Test1 {
        @Test
        public void test(){
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            Book book = context.getBean("book", Book.class);
            System.out.println(book);
        }
    }
    

    image-20220724001645781

2.4.6 完全注解开发

创建配置类,替代 xml 配置文件

@Configuration
@ComponentScan(value = "atguigu")
public class SpringConfig {
}

代码测试

public class Test1 {
    @Test
    public void test(){
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
    }
}

image-20220724002302892

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值