快速梳理Spring知識點 - IOC

目錄

一、Spring框架概述

二靴姿、Sping 初體驗

三沃但、IOC容器

?1. IOC概念和原理

?2. IOC接口(BeanFactory)

?3. Bean管理什么是Bean管理?

??IOC操作Bean管理(基于xml)

??IOC操作Bean管理(基于注解)

?4. Bean的作用域

?5. Bean的生命周期

?6. 引入外部屬性文件

一佛吓、Spring框架概述

  1. Spring 是輕量級的開源JavaEE 框架
  2. Spring 可以解決企業(yè)應用開發(fā)的復雜性
  3. Spring 的兩個核心部分:IOC 和 AOP
    • IOC: 控制反轉(zhuǎn)宵晚,把創(chuàng)建對象的過程交給Spring 進行管理
    • AOP: 面向切面,不修改源代碼進行功能增強
  4. Spring 特點
    • 方便解耦辈毯,簡化開發(fā)
    • AOP編程支持
    • 方便程序測試
    • 方便和其他框架進行整和
    • 方便進行事務操作
    • 降低API開發(fā)難度

二坝疼、Sping 初體驗

  1. 創(chuàng)建一個maven項目

  2. 引入spring5.x版本基礎jar包

    core搜贤、context谆沃、aop、expression (commons-logging 非Spring框架內(nèi))

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    
  1. 創(chuàng)建一個普通類仪芒,在這個類創(chuàng)建普通方法

    public class User {
        public void add() {
            System.out.println("add...");
        }
    }
    
  2. 創(chuàng)建Spring配置文件唁影,在配置文件配置創(chuàng)建的對象

    • Spring配置文件使用xml
    • 創(chuàng)建bean1.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對象創(chuàng)建-->
        <bean id="user" class="com.yang.spring5.User"></bean>
    </beans>
    
  3. 進行測試編碼

    public class Spring5Test {
    
        @Test
        public void testAdd() {
            //1 加載spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    
            //2 獲取配置創(chuàng)建的對象
            User user = context.getBean("user", User.class);
    
            System.out.println(user);
            user.add();
        }
    }
    

三、IOC容器

1. IOC概念和原理

  • 什么是IOC ?

控制反轉(zhuǎn)掂名,把對象創(chuàng)建和對象之間的調(diào)用過程据沈,交給spring管理

使用IOC的目的:為了降低耦合度

  • IOC底層原理

主要使用了xml解析、工廠模式饺蔑、反射

  • IOC過程

    • 第一步 xml配置文件锌介,配置要創(chuàng)建的對象
    <!--配置User對象創(chuàng)建-->
    <bean id="user" class="com.yang.spring5.User"></bean>
    
    • 第二步 創(chuàng)建工廠類,通過xml解析猾警,獲取class屬性值孔祸,再通過反射創(chuàng)建對象

2. IOC接口(BeanFactory)

  • IOC思想是基于IOC容器完成的,IOC容器的底層就是對象工廠

  • Spring提供IOC容器實現(xiàn)的兩種方式

    • BeanFactory:IOC容器基本實現(xiàn)发皿,Spring內(nèi)部使用接口崔慧,不提供開發(fā)人員使用

    加載配置文件的時候不會創(chuàng)建對象,獲取對象的時候才會去創(chuàng)建對象

    • ApplicationCpntext:BeanFactory的子接口穴墅,功能更加強大惶室,一般由開發(fā)人員使用

    加載配置文件的時候就會把配置文件中的對象進行創(chuàng)建

    加載配置文件的兩個實現(xiàn)類
    - ClassPathXmlApplicationContext
    - FileSystemXmlApplicationContext
    
    這兩個實現(xiàn)類的區(qū)別
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");//類路徑
    ApplicationContext context = new FileSystemXmlApplicationContext("D:\\Java_learning\\spring-learning\\src\\main\\resources\\bean1.xml");//絕對路徑
    

3. Bean管理

什么是Bean管理温自?

Bean管理實際上是指兩個操作

  1. Spring創(chuàng)建對象
  2. Spring注入屬性

IOC操作Bean管理(基于xml)

  • 在Spring配置文件中,使用bean標簽皇钞,標簽里添加對應屬性悼泌,就可以實現(xiàn)對象創(chuàng)建。
<!--配置User對象創(chuàng)建-->
<bean id="user" class="com.yang.spring5.User"></bean>
  • bean標簽中常用屬性
    • id:唯一標識
    • class:類全路徑
    • name:類似與id屬性夹界,區(qū)別是name可以加特殊標識券躁,如 “/” 等。
  • 創(chuàng)建對象的時候掉盅,默認執(zhí)行無參構(gòu)造方法也拜,完成對象創(chuàng)建。
  • 屬性注入(DI)

    set注入趾痘、構(gòu)造器注入慢哈、P名稱空間注入

    • 第一種:使用set方法注入。
    1. 創(chuàng)建類永票,定義屬性和它的set方法
    /**
     * @Author: csy
     * @Date: 2020/12/17 20:38
     * @Description: 使用set方法進行屬性注入
     */
    public class Book {
    
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void show() {
            System.out.println("name:" + name);
        }
    }
    
    1. 在spring配置文件中卵贱,配置對象創(chuàng)建和屬性注入
    <!--配置Book對象創(chuàng)建-->
    <bean id="book" class="com.yang.spring5.Book">
        <!--使用property完成屬性注入-->
        <property name="name" value="語文"></property>
    </bean>
    
    1. 測試
    public class Spring5Test {
    
        @Test
        public void testAdd() {
            //1 加載spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            //2 獲取配置創(chuàng)建的對象
            Book book = context.getBean("book", Book.class);
            book.show();
        }
    }
    
    1. 輸出
    name:語文
    
    • 第二種:使用有參構(gòu)造方法注入。
    1. 創(chuàng)建類侣集,定義屬性和有參構(gòu)造方法键俱。
    /**
     * @Author: csy
     * @Date: 2020/12/17 21:15
     * @Description: 使用有參構(gòu)造方法注入
     */
    public class Orders {
    
        private String name;
    
        public Orders(String name) {
            this.name = name;
        }
    
        public void show(){
            System.out.println("name:"+ name);
        }
    }
    
    1. 在Spring配置文件中,配置對象創(chuàng)建和屬性注入
    <!--配置Orders對象創(chuàng)建-->
    <bean id="orders" class="com.yang.spring5.Orders">
        <!--使用 constructor-arg 完成屬性注入-->
        <constructor-arg name="name" value="銷售訂單"/>
    </bean>
    
    1. 測試
    public class Spring5Test {
    
        @Test
        public void testAdd() {
            //1 加載spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            //2 獲取配置創(chuàng)建的對象
            Orders orders = context.getBean("orders", Orders.class);
            orders.show();
        }
    }
    
    1. 結(jié)果
    name:銷售訂單
    
    • 第三種:P名稱空間注入

      使用P名稱空間注入世分,可以簡化基于XML配置方式

    1. 在配置文件中添加P名稱空間
    xmlns:p="http://www.springframework.org/schema/p"
    
    1. 配置對象創(chuàng)建和屬性注入
    <?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">
    
      <!--使用P標簽注入-->
      <bean id="book" class="com.yang.spring5.Book" p:name="數(shù)學">
      </bean>
    
    </beans>
    
  • 特殊類型值注入
    • null
    <!--通過<null></null>標簽注入-->
    <!--配置Book對象創(chuàng)建-->
    <bean id="book" class="com.yang.spring5.Book">
     <!--使用property完成屬性注入-->
     <property name="name">
         <null></null>
     </property>
    </bean>
    
    • 特殊符號
    <!--1.把特殊符號轉(zhuǎn)義-->
    <!--2.把帶特殊符號的內(nèi)容寫到CDATA中-->
    <!--配置Book對象創(chuàng)建-->
    <bean id="book" class="com.yang.spring5.Book">
        <!--使用property完成屬性注入-->
        <property name="name">
            <value><![CDATA[<<語文>>]]></value>
        </property>
    </bean>
    
  • 注入屬性-外部bean

    場景:service類中引用dao類

    代碼示例:

    1. 創(chuàng)建兩個類编振,service類和dao類
    2. 在service類中調(diào)用dao里的方法
    3. 在spring配置文件中進行配置
    public class UserService {
    
        /**
         * 創(chuàng)建UserDao類型屬性,生成set方法
         */
        private UserDao userDao;
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void add() {
            System.out.println("service add....");
            userDao.update();
        }
    }
    
    public interface UserDao {
        public void update();
    }
    
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void update() {
            System.out.println("dao update....");
        }
    }
    
    <?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="com.yang.spring5.service.UserService">
            <!--  注入userDao對象    -->
            <!--  name屬性:類里的屬性名稱   -->
            <!--  ref屬性:創(chuàng)建userDao對象bean標簽id值 -->
            <property name="userDao" ref="userDao"></property>
        </bean>
        <bean id="userDao" class="com.yang.spring5.dao.UserDaoImpl"></bean>
    </beans>
    
    public class Spring5Test2 {
    
        @Test
        public void testAdd() {
            //1 加載spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
            //2 獲取配置創(chuàng)建的對象
            UserService userService = context.getBean("userService", UserService.class);
            userService.add();
        }
    
    }
    
  • 注入屬性-內(nèi)部bean和級聯(lián)賦值

    內(nèi)部bean

    場景:員工和部門(一對多關系)

    一個部門有多個員工臭埋,一個員工屬于一個部門

    部門是一踪央,員工是多

    代碼實例:

    1. 創(chuàng)建員工類與部門類(員工類中有部門屬性)
    2. xml配置文件中進行內(nèi)部bean配置
    package com.yang.spring5.bean;
    
    /**
     * @Description: 部門
     * @author: caoshenyang
     * @date: 2020.12.31
     */
    public class Dept {
    
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Dept{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    package com.yang.spring5.bean;
    
    /**
     * @Description: 員工
     * @author: caoshenyang
     * @date: 2020.12.31
     */
    public class Emp {
    
        private String name;
        private String gender;
        private Dept dept;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    
        @Override
        public String toString() {
            return "Emp{" +
                    "name='" + name + '\'' +
                    ", gender='" + gender + '\'' +
                    ", dept=" + dept +
                    '}';
        }
    }
    
    <?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 name="emp" class="com.yang.spring5.bean.Emp">
            <property name="name" value="張三"></property>
            <property name="gender" value="男"></property>
            <!--內(nèi)部bean注入-->
            <!--當然也可以采用外部bean的方式來實現(xiàn) 1.外部創(chuàng)建dept的bean 2.內(nèi)部通過ref標簽引用-->
            <property name="dept" >
                <bean id="dept" class="com.yang.spring5.bean.Dept">
                    <property name="name" value="IT部門"></property>
                </bean>
            </property>
        </bean>
    </beans>
    
    package com.yang.spring5.testdemo;
    
    import com.yang.spring5.bean.Emp;
    import com.yang.spring5.service.UserService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @Author: csy
     * @Date: 2020/12/28 22:16
     * @Description:
     */
    public class Spring5Test3 {
    
        @Test
        public void testAdd() {
            //1 加載spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
            //2 獲取配置創(chuàng)建的對象
            Emp emp = context.getBean("emp", Emp.class);
            System.out.println(emp);
        }
    }
    

    輸出:

    Emp{name='張三', gender='男', dept=Dept{name='IT部門'}}
    

    級聯(lián)賦值

    <?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 name="emp" class="com.yang.spring5.bean.Emp">
            <property name="name" value="張三"></property>
            <property name="gender" value="男"></property>
            <!--內(nèi)部bean注入-->
            <!--當然也可以采用外部bean的方式來實現(xiàn) 1.外部創(chuàng)建dept的bean 2.內(nèi)部通過ref標簽引用-->
            <property name="dept" ref="dept" > </property>
            <!--依賴于get方法獲取dept對象,然后給dept對象屬性賦值瓢阴,所以在Emp對象中需要實現(xiàn)對應的get方法-->
            <property name="dept.name" value="財務部門"></property>
        </bean>
        <bean id="dept" class="com.yang.spring5.bean.Dept"></bean>
    </beans>
    
    package com.yang.spring5.testdemo;
    
    import com.yang.spring5.bean.Emp;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @Author: csy
     * @Date: 2020/12/28 22:16
     * @Description:
     */
    public class Spring5Test4 {
    
        @Test
        public void testAdd() {
            //1 加載spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
            //2 獲取配置創(chuàng)建的對象
            Emp emp = context.getBean("emp", Emp.class);
            System.out.println(emp);
        }
    }
    

    輸出:

    Emp{name='張三', gender='男', dept=Dept{name='財務部門'}
    
  • 注入集合屬性
    • 注入數(shù)組類型屬性
    • 注入List集合屬性
    • 注入Map集合屬性
    • 注入Set集合屬性

    場景:當我們需要注入集合類型屬性值的時候

    代碼示例:

    1. 創(chuàng)建Stu類
    2. xml配置
    package com.yang.spring5.bean;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @Description: 學生
     * @author: caoshenyang
     * @date: 2020.12.31
     */
    public class Student {
    
        private String[] course;
    
        private List<String> lists;
    
        private Map<String, String> maps;
    
        private Set<String> sets;
    
        public void setCourse(String[] course) {
            this.course = course;
        }
    
        public void setLists(List<String> lists) {
            this.lists = lists;
        }
    
        public void setMaps(Map<String, String> maps) {
            this.maps = maps;
        }
    
        public void setSets(Set<String> sets) {
            this.sets = sets;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "course=" + Arrays.toString(course) +
                    ", lists=" + lists +
                    ", maps=" + maps +
                    ", sets=" + sets +
                    '}';
        }
    }
    
    <?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 name="student" class="com.yang.spring5.bean.Student">
            <property name="course">
                <array>
                    <value>語文</value>
                    <value>數(shù)學</value>
                </array>
            </property>
            <property name="lists">
                <list>
                    <value>JAVA</value>
                    <value>C語言</value>
                </list>
            </property>
            <property name="maps">
                <map>
                    <entry key="1" value="MySql"/>
                    <entry key="2" value="Redis"/>
                </map>
            </property>
            <property name="sets">
                <set>
                    <value>C++</value>
                    <value>C#</value>
                </set>
            </property>
        </bean>
    </beans>
    

    輸出:

    Student{course=[語文, 數(shù)學], lists=[JAVA, C語言], maps={1=MySql, 2=Redis}, sets=[C++, C#]}
    
  • 在集合里設置對象類型值

    場景:教師類的課程屬性為課程類

    1. 創(chuàng)建2個類Teacher類和Course類
    2. xml配置

    代碼示例:

    package com.yang.spring5.bean;
    
    import java.util.List;
    
    /**
     * @Description: 教師
     * @author: caoshenyang
     * @date: 2020.12.31
     */
    public class Teacher {
    
       private List<Course> courses;
    
        public void setCourses(List<Course> courses) {
            this.courses = courses;
        }
    
        @Override
        public String toString() {
            return "Teacher{" +
                    "courses=" + courses +
                    '}';
        }
    }
    
    package com.yang.spring5.bean;
    
    /**
     * @Description: 課程
     * @author: caoshenyang
     * @date: 2020.12.31
     */
    public class Course {
    
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Course{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    <?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 name="teacher" class="com.yang.spring5.bean.Teacher">
            <property name="courses">
                <list>
                    <ref bean="course1"/>
                    <ref bean="course2"/>
                </list>
            </property>
    
        </bean>
    
        <bean name="course1" class="com.yang.spring5.bean.Course">
            <property name="name" value="JAVA"/>
        </bean>
        <bean name="course2" class="com.yang.spring5.bean.Course">
            <property name="name" value="VUE"/>
        </bean>
    </beans>
    

    輸出:

    Teacher{courses=[Course{name='JAVA'}, Course{name='VUE'}]}
    
  • 把集合注入部分提取出來
    1. spring配置文件中引入名稱空間util
  1. 使用util標簽完成list集合注入提取
<?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 id="courses">
        <ref bean="course1"/>
        <ref bean="course2"/>
    </util:list>

    <bean name="teacher" class="com.yang.spring5.bean.Teacher">
        <property name="courses" ref="courses"/>
    </bean>

    <bean name="course1" class="com.yang.spring5.bean.Course">
        <property name="name" value="JAVA"/>
    </bean>
    <bean name="course2" class="com.yang.spring5.bean.Course">
        <property name="name" value="VUE"/>
    </bean>
</beans>

輸出:

Teacher{courses=[Course{name='JAVA'}, Course{name='VUE'}]}
  • FactoryBean
    • 普通bean:xml中定義什么類型的bean畅蹂,即返回什么類型的bean

    前面介紹的都為普通bean

    • 工廠bean:xml中定義的類型可以和返回的類型不一樣

    代碼示例:

    1. 創(chuàng)建工廠類,實現(xiàn)FactoryBean接口
    2. 實現(xiàn)接口中的方法荣恐,在方法中定義返回的類型
package com.yang.spring5.factoryBean;

import com.yang.spring5.bean.Course;
import org.springframework.beans.factory.FactoryBean;

/**
* @Description: 工廠bean
* @author: caoshenyang
* @date: 2020.12.31
*/
public class MyFactoryBean implements FactoryBean<Course> {
   @Override
   public Course getObject() throws Exception {
       Course course = new Course();
       course.setName("JAVA");
       return course;
   }

   @Override
   public Class<?> getObjectType() {
       return null;
   }

   @Override
   public boolean isSingleton() {
       return false;
   }
}
<?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 name="myFactoryBean" class="com.yang.spring5.factoryBean.MyFactoryBean"></bean>
</beans>
package com.yang.spring5.testdemo;

import com.yang.spring5.bean.Course;
import com.yang.spring5.bean.Teacher;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* @Author: csy
* @Date: 2020/12/28 22:16
* @Description:
*/
public class Spring5Test8 {

   @Test
   public void testAdd() {
       //1 加載spring配置文件
       ApplicationContext context = new ClassPathXmlApplicationContext("bean8.xml");
       //2 獲取配置創(chuàng)建的對象
       Course course = context.getBean("myFactoryBean", Course.class);
       System.out.println(course);
   }

}

輸出:

Course{name='JAVA'}

IOC操作Bean管理(基于注解)

  1. 什么是注解

    (1)注解是代碼特殊標記液斜,格式:@注解名稱(屬性名稱=屬性值, 屬性名稱=屬性值…)

    (2)使用注解,注解作用在類上面叠穆,方法上面少漆,屬性上面

    (3)使用注解目的:簡化 xml 配置

  2. Spring針對Bean管理提供的注解(下面四個注解功能一樣,都可以用來創(chuàng)建實例)

    (1)@Component

    (2)@Service

    (3)@Controller

    (4)@Repository

  3. 基于注解方式實現(xiàn)對象創(chuàng)建

    (1)引入AOP依賴

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

    (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"
           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">
    
        <!--開啟注解掃描
            1.掃描多個包痹束,多個包使用逗號隔開
            2.掃描包的上層目錄
        -->
        <context:component-scan base-package="com.yang.spring5"></context:component-scan>
    </beans>
    

    (3)創(chuàng)建類检疫,加上注解

    //在注解里面 value 屬性值可以省略不寫,
    //默認值是類名稱祷嘶,首字母小寫
    //StudentService -- studentService
    @Service(value = "studentService") //注解等同于XML配置文件:<bean id="studentService" class=".."/>
    public class StudentService {
        public void show() {
            System.out.println("service show ......");
        }
    }
    

    測試:

    @Test
    public void testAdd() {
        //1 加載spring配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean12.xml");
        //2 獲取配置創(chuàng)建的對象
        StudentService studentService = context.getBean("studentService", StudentService.class);
        studentService.show();
    }
    

    輸出:

    service show ......
    
  4. 開啟組件掃描細節(jié)配置

<!--示例 1
     use-default-filters="false" 表示現(xiàn)在不使用默認 filter屎媳,自己配置 filter
     context:include-filter 夺溢,設置掃描哪些內(nèi)容
-->
<context:component-scan base-package="com.yang.spring5" use-default-filters="false">
    <!--代表只掃描Controller注解的類-->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--示例 2
 下面配置掃描包所有內(nèi)容
 context:exclude-filter: 設置哪些內(nèi)容不進行掃描
-->
<context:component-scan base-package="com.yang.spring5">
    <!--表示Controller注解的類之外一切都進行掃描-->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
  1. 基于注解方式實現(xiàn)屬性注入

    (1)@AutoWired:根據(jù)屬性類型進行自動裝配

    ? 第一步 把 service 和 dao 對象創(chuàng)建矛洞,在 service 和 dao 類添加創(chuàng)建對象注解

    ? 第二步 在 service 注入 dao 對象床未,在 service 類添加 dao 類型屬性,在屬性上面使用注解

    @Service
    public class UserService {
     //定義 dao 類型屬性
     //不需要添加 set 方法
     //添加注入屬性注解
     @Autowired
     private UserDao userDao;
     public void add() {
     System.out.println("service add.......");
     userDao.add();
     }
    }
    
    //Dao實現(xiàn)類
    @Repository
    public class UserDaoImpl implements UserDao {
        @Override
        public void add() {
            System.out.println("dao add.....");
        }
    }
    

    (2)@Qualifier:根據(jù)屬性名稱進行注入羡亩,這個@Qualifier 注解的使用丹禀,和上面@Autowired 一起使用

    @Autowired
    //根據(jù)名稱進行注入(目的在于區(qū)別同一接口下有多個實現(xiàn)類状勤,根據(jù)類型就無法選擇,從而出錯K帷)
    @Qualifier(value = "userDaoImpl1") 
    private UserDao userDao;
    

    (3)@Resource:可以根據(jù)類型注入持搜,也可以根據(jù)名稱注入

    //@Resource //根據(jù)類型進行注入
    @Resource(name = "userDaoImpl1") //根據(jù)名稱進行注入
    private UserDao userDao;
    

    (4)@Value:普通類型值注入

    @Value(value = "abc")
    private String name
    
  2. 完全注解開發(fā)

    (1)創(chuàng)建配置類,替換xml配置文件

    @Configuration //作為配置類焙矛,替代 xml 配置文件
    @ComponentScan(basePackages = {"com.yang.spring5"})
    public class SpringConfig {
        
    }
    

    (2)編寫測試類

    @Test
    public void testService2() {
     //加載配置類
     ApplicationContext context
     = new AnnotationConfigApplicationContext(SpringConfig.class);
     UserService userService = context.getBean("userService",
    UserService.class);
     System.out.println(userService);
     userService.add();
    }
    

4. Bean的作用域

bean作用域是用來確定從Spring容器中返回哪種類型的bean實例給調(diào)用者葫盼。

  1. spring里配置的bean是單例還是多實例的?

    默認為單例村斟,可進行配置 使用 scope 標簽贫导, prototype 多實例 、 singleton 單例 (默認)

    <--多實例-->
    <bean id="user" class="com.yang.spring5.User" scope="prototype"></bean>
    <--單例-->
    <bean id="user" class="com.yang.spring5.User" scope="singleton "></bean>
    
  2. scope設置prototypesingleton 的區(qū)別蟆盹?

    1. singleton 單例 prototype 多實例
    2. singleton bean在配置加載的時候進行創(chuàng)建孩灯,prototype bean在調(diào)用getBean方法的時候創(chuàng)建

5. Bean的生命周期

從對象創(chuàng)建到對象銷毀的過程(5步)

  1. 通過構(gòu)造器創(chuàng)建 bean 實例(無參數(shù)構(gòu)造)

  2. 為 bean 的屬性設置值和對其他 bean 引用(調(diào)用 set 方法)

  3. 調(diào)用 bean 的初始化的方法(需要進行配置初始化的方法,調(diào)用init方法)

  4. bean 可以使用了(對象獲取到了逾滥,調(diào)用getBean方法)

  5. 當容器關閉時候峰档,調(diào)用 bean 的銷毀的方法(需要進行配置銷毀的方法,調(diào)用destroy方法)

代碼示例

package com.yang.spring5.bean;

/**
 * @Description: 訂單
 * @author: caoshenyang
 * @date: 2021.01.04
 */
public class Order {
    private String name;

    public Order() {
        System.out.println("第一步 執(zhí)行無參構(gòu)造方法創(chuàng)建 bean 實例");
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("第二步 調(diào)用setter方法設置屬性值");
    }

    public void initMethod(){
        System.out.println("第三步 執(zhí)行初始化方法");
    }

    public void destroyMethod(){
        System.out.println("第五步 執(zhí)行銷毀方法");
    }
}
<?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="order" class="com.yang.spring5.bean.Order" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="手機"/>
    </bean>
</beans>
@Test
public void testAdd() {
    //1 加載spring配置文件
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean9.xml");
    //2 獲取配置創(chuàng)建的對象
    Order order = context.getBean("order", Order.class);
    System.out.println("第四步 獲取創(chuàng)建bean實例對象");
    System.out.println(order);

    context.close();
}

輸出:

第一步 執(zhí)行無參構(gòu)造方法創(chuàng)建 bean 實例
第二步 調(diào)用setter方法設置屬性值
第三步 執(zhí)行初始化方法
第四步 獲取創(chuàng)建bean實例對象
com.yang.spring5.bean.Order@ed9d034
第五步 執(zhí)行銷毀方法

添加bean的后置處理器(bean的生命周期為7步)

  1. 創(chuàng)建后置處理器類匣距,需要實現(xiàn)BeanPostProcessor接口
  2. 配置后置處理器
package com.yang.spring5.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * @Description: 后置處理器
 * @author: caoshenyang
 * @date: 2021.01.04
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前執(zhí)行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后執(zhí)行的方法");
        return 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="order" class="com.yang.spring5.bean.Order" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="手機"/>
    </bean>
    <!--配置后置處理器-->
    <bean id="myBeanPostProcessor" class="com.yang.spring5.bean.MyBeanPostProcessor"></bean>
</beans>
@Test
public void testAdd() {
    //1 加載spring配置文件
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean9.xml");
    //2 獲取配置創(chuàng)建的對象
    Order order = context.getBean("order", Order.class);
    System.out.println("第四步 獲取創(chuàng)建bean實例對象");
    System.out.println(order);

    context.close();
}

輸出:

第一步 執(zhí)行無參構(gòu)造方法創(chuàng)建 bean 實例
第二步 調(diào)用setter方法設置屬性值
在初始化之前執(zhí)行的方法
第三步 執(zhí)行初始化方法
在初始化之后執(zhí)行的方法
第四步 獲取創(chuàng)建bean實例對象
com.yang.spring5.bean.Order@4eb7f003
第五步 執(zhí)行銷毀方法

6. 引入外部屬性文件

下面以配置數(shù)據(jù)庫連接作為示例面哥。

  • 方式一:直接配置數(shù)據(jù)庫信息
  1. 引入Druid連接池依賴
  2. 配置連接池
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.2.4</version>
</dependency>
<!--直接配置連接池-->
<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>
  • 方式二:引入外部屬性文件配置數(shù)據(jù)庫連接池
  1. 創(chuàng)建外部屬性文件,properties類型文件(jdbc.properties)
  2. 寫數(shù)據(jù)庫信息
  3. 引入到Spring配置文件中
    1. 設置context名稱空間
    2. 引入數(shù)據(jù)
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=root
<?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:jdbc.properties"/>

    <!--配置連接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${prop.driverClass}"></property>
        <property name="url" value="${prop.url}"></property>
        <property name="username" value="${prop.userName}"></property>
        <property name="password" value="${prop.password}"></property>
    </bean>
</beans>
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毅待,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子归榕,更是在濱河造成了極大的恐慌尸红,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刹泄,死亡現(xiàn)場離奇詭異外里,居然都是意外死亡,警方通過查閱死者的電腦和手機特石,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門盅蝗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姆蘸,你說我怎么就攤上這事墩莫≤轿” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵狂秦,是天一觀的道長灌侣。 經(jīng)常有香客問我,道長裂问,這世上最難降的妖魔是什么侧啼? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮堪簿,結(jié)果婚禮上痊乾,老公的妹妹穿的比我還像新娘。我一直安慰自己椭更,他們只是感情好符喝,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甜孤,像睡著了一般协饲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缴川,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天茉稠,我揣著相機與錄音,去河邊找鬼把夸。 笑死而线,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的恋日。 我是一名探鬼主播膀篮,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岂膳!你這毒婦竟也來了誓竿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤谈截,失蹤者是張志新(化名)和其女友劉穎筷屡,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體簸喂,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡毙死,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喻鳄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扼倘。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖除呵,靈堂內(nèi)的尸體忽然破棺而出再菊,到底是詐尸還是另有隱情爪喘,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布袄简,位于F島的核電站腥放,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绿语。R本人自食惡果不足惜秃症,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吕粹。 院中可真熱鬧种柑,春花似錦、人聲如沸匹耕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稳其。三九已至驶赏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間既鞠,已是汗流浹背煤傍。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嘱蛋,地道東北人蚯姆。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像洒敏,于是被迫代替她去往敵國和親龄恋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容