1. 什么是框架
框架指的是针对某一个(某一系列)共性问题的通用解决方案
2. 为什么要学习spring,spring能给我们带来什么
- 为什么要学习spring
- 为什么需要面向接口编程
- 耦合、依赖的概念
- IOC和DI的概念
3. spring的概念
- 
广义的spring指的是spring的生态:spring,springMVC,springboot,spring cloud,spring security,spring data等 
- 
狭义的spring。指的就是spring framework本身。 它是其他spring框架的基础。很重要! 
4. spring中的IOC容器
ApplicationContext是spring的IOC容器。是一个接口。
ApplicationContext的父接口,也就是顶层接口是:BeanFactory
平时我们常用的有:ClassPathXmlApplicationContext , AnnotationConfigApplicationContext
5. spring的快速入门
添加依赖
            
            
              java
              
              
            
          
          <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <servlet.version>6.0.0</servlet.version>
    <junit.version>5.10.1</junit.version>
    <mysql.version>8.0.32</mysql.version>
    <spring.version>6.0.11</spring.version>
    <lombok.version>1.18.24</lombok.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>新建Person类
            
            
              java
              
              
            
          
          public class Person {
    public void sayHello(){
        System.out.println("大家好,肚子好饿!");
    }
}新建spring的IOC配置文件:applicationContext.xml , 在其中描述Person
            
            
              xml
              
              
            
          
          <bean id="p01" class="com.bottom.ioc.Person"/>测试,从IOC容器中获取person实例对象


6. 获取bean的方式
Object getBean(id)
            
            
              java
              
              
            
          
          @Test
public void test01(){
    System.out.println(beanFactory.getBean("p01"));
}
T getBean(Class)
            
            
              java
              
              
            
          
          @Test
public void test01(){
    System.out.println(beanFactory.getBean(Person.class));
}
T getBean(id,Class)
            
            
              java
              
              
            
          
          @Test
public void test01(){
    System.out.println(beanFactory.getBean("p01",Person.class));
}
注意点:
- 根据id获取,有可能获取不到,获取不到则报错 NoSuchBeanDefinitionException: No bean named 'p02' available
- 根据类型获取,有且唯一,则获取成功;否则报错 NoUniqueBeanDefinitionException:expected single matching bean but found 2: p01,p02 小结:
- 根据id获取,返回Object类型。没有则报错
- 根据class获取,直接返回对应的类型。如果没有或不唯一则报错。
- 同时根据id和class获取。
7. spring的IOC容器实质上也是通过反射技术去创建bean实例
- 创建Bean实例的方式一
8. 属性赋值
- setter赋值 spring通过反射技术调用对象中的setter方法,从而完成属性赋值
            
            
              xml
              
              
            
          
          <bean id="s01" class="com.bottom.ioc.Student">
   <property name="sid" value="s001"/>
   <property name="sname" value="鸠摩智"/>
   <property name="age" value="30"/>
</bean>- ref赋值
            
            
              xml
              
              
            
          
          <bean id="t01" class="com.bottom.ioc.Teacher">
  <property name="tname" value="爱因斯坦"/>
  <property name="book" ref="b01"/>    <!-- reference:引用 -->
</bean>- 内部bean赋值
            
            
              xml
              
              
            
          
          <bean id="t02" class="com.bottom.ioc.Teacher">
   <property name="tname" value="爱迪生"/>
   <property name="book">
       <bean class="com.bottom.ioc.Book">
           <property name="bookName" value="MySQL从删库到跑路"/>
           <property name="price" value="98"/>
       </bean>
   </property>
</bean>- 
导入properties文件给属性赋值 两个注意点: ① properties文件中,等号两边不要有空格 ② properties文件中的key,一般是由多个单词组成,目的是为了避免和系统的某些属性名冲突,从而导致你获取到的是系统属性值 
            
            
              xml
              
              
            
          
          <!-- 1.先引入properties文件 -->
<context:property-placeholder location="classpath:car.properties" file-encoding="UTF-8"/>
            
            
              xml
              
              
            
          
          <!-- 2.使用properties文件中的值给属性赋值 -->
<bean id="car01" class="com.bottom.ioc.Car">
    <property name="cid" value="${cid}"/>
    <property name="cname" value="${cname}"/>
    <property name="price" value="${price}"/>
    <property name="username" value="${username}"/>
</bean>- 构造器注入
            
            
              xml
              
              
            
          
          <!-- Ambiguous:模棱两可的 -->
<bean id="tiger001" class="com.bottom.ioc.Tiger">
    <constructor-arg value="3" index="1" type="java.lang.Integer" name="age"/>
    <constructor-arg value="东北虎"/>
</bean>- P名称空间
            
            
              xml
              
              
            
          
          <!-- 通过p名称空间给属性赋值 -->
<bean id="book002" class="com.bottom.ioc.Book" p:bookName="PHP是全世界最好的语言" p:price="96"/>- 属性级联
            
            
              xml
              
              
            
          
          <!-- 级联属性赋值 -->
<bean id="book001" class="com.bottom.ioc.Book"/>
<bean id="tea001" class="com.bottom.ioc.Teacher">
    <property name="tname" value="牛顿"/>
    <property name="book" ref="book001"/>
    <property name="book.bookName" value="21天精通C++"/>
    <property name="book.price" value="97"/>
</bean>- 数组或集合类型的属性
            
            
              xml
              
              
            
          
          <!-- 属性赋值,属性是:数组、List、Set、Map、Properties -->
<bean id="zoo" class="com.bottom.ioc.Zoo">
    <property name="zooName" value="深圳动物园"/>
    <property name="tigerArr">
        <array>
            <ref bean="tiger01"/>
            <ref bean="tiger02"/>
            <ref bean="tiger03"/>
        </array>
    </property>
    <property name="tigerList">
        <list>
            <ref bean="tiger02"/>
            <ref bean="tiger03"/>
        </list>
    </property>
    <property name="tigerSet">
        <set>
            <ref bean="tiger04"/>
        </set>
    </property>
    <property name="tigerMap">
        <map>
            <entry key="t001" value-ref="tiger01"/>
            <entry key="t002" value-ref="tiger02"/>
            <entry key="t003" value-ref="tiger03"/>
            <entry key="t004" value-ref="tiger04"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="tiger001">东北虎</prop>
            <prop key="tiger002">华南虎</prop>
        </props>
    </property>
</bean>- 集合类型的bean对象
            
            
              xml
              
              
            
          
          <util:list id="tigerList">
    <list>
        <ref bean="tiger02"/>
        <ref bean="tiger03"/>
    </list>
</util:list>9. 通过静态工厂方法创建bean实例
创建Bean实例的方式二
1.创建 Car类
            
            
              java
              
              
            
          
          @Data
public class Car {
   private Integer cid ;
   private String cname ;
   private Integer price ;
   private String username;
}2.创建CarFactory
            
            
              java
              
              
            
          
          public class CarFactory {
   //静态的工厂方法
   public static Car getCarInstance(){
       Car car = new Car();
       car.setCid(99);
       car.setCname("大众捷达");
       car.setPrice(50);
       return car ;
   }
}3.在xml注入bean信息
            
            
              xml
              
              
            
          
          <!-- car99这个对象需要通过CarFactory这个类的getCarInstance方法产生 -->
<bean id="car99" class="com.bottom.ioc.CarFactory" factory-method="getCarInstance"/>4.在测试类测试
            
            
              java
              
              
            
          
          @Test
public void test10(){
   System.out.println(beanFactory.getBean("car99"));
}
10. 通过工厂方法创建bean实例
创建Bean实例的方式三
1.创建book 类
            
            
              java
              
              
            
          
          @Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
    private String bookName ;
    private double price ;
}2.创建 BookFactory
            
            
              java
              
              
            
          
          public class BookFactory {
    public Book getBookInstance(){
        Book book = new Book("Spring从入门到精通",101);
        return book ;
    }
}3.在xml注入bean信息
            
            
              xml
              
              
            
          
          <!-- car99这个对象需要通过CarFactory这个类的getCarInstance方法产生 -->
<bean id="car99" class="com.bottom.ioc.CarFactory" factory-method="getCarInstance"/>4.在测试类测试
            
            
              java
              
              
            
          
          @Test
public void test11(){
    System.out.println(beanFactory.getBean("book99"));
}
11. scope的取值
- 
singleton : 默认值,单例 
- 
prototype : 多例 

12. bean的初始化方法和销毁方法(指定bean在初始化和销毁时分别调用的方法)
1.创建dog类
            
            
              java
              
              
            
          
          public class Dog {
    public Dog(){
        System.out.println("Dog无参构造方法被调用...");
    }
    public void dogInit(){
        System.out.println("Dog正在初始化...");
    }
    public void dogDestroy(){
        System.out.println("Dog正在销毁....");
    }
}2.在xml注入bean信息
            
            
              xml
              
              
            
          
          <bean id="dog" class="com.bottom.ioc.Dog" init-method="dogInit" destroy-method="dogDestroy"/>3.在测试类测试
            
            
              java
              
              
            
          
          @Test
public void test02(){
    beanFactory.getBean(Dog.class);
    ((ClassPathXmlApplicationContext)beanFactory).close();
}
13.通过FactoryBean机制创建Bean实例
创建Bean实例的方式四
1.创建cat类
            
            
              java
              
              
            
          
          @Data
public class Cat {
    private String cname ;
    private Integer age ;
}2.创建CatFactoryBean
            
            
              java
              
              
            
          
          public class CatFactoryBean implements FactoryBean<Cat> {
    @Override
    public Cat getObject() throws Exception {
        Cat cat = new Cat();
        cat.setCname("tom");
        cat.setAge(2);
        return cat;
    }
    @Override
    public Class<?> getObjectType() {
        return Cat.class;
    }
}3.在xml注入bean信息
            
            
              xml
              
              
            
          
          <!-- 通过FactoryBean机制产生bean实例 -->
<bean id="cat01" class="com.bottom.ioc.CatFactoryBean"/>4.在测试类测试
            
            
              csharp
              
              
            
          
          @Test
public void test03(){
    System.out.println(beanFactory.getBean("cat01"));
}
14.bean的生命周期(重要)
- IOC容器中的bean实例默认是单例的;
- 单例的实例是在容器创建的时候就产生了;多例是在要使用时才会产生。
- BeanPostProcessor-Bean后置处理器 如果在bean实例初始化的前后有需要做的事情,我们可以使用后置处理器实现