🌐 Spring IOC 学习

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. 属性赋值

  1. 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>
  1. ref赋值
xml 复制代码
<bean id="t01" class="com.bottom.ioc.Teacher">
  <property name="tname" value="爱因斯坦"/>
  <property name="book" ref="b01"/>    <!-- reference:引用 -->
</bean>
  1. 内部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>
  1. 导入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>
  1. 构造器注入
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>
  1. P名称空间
xml 复制代码
<!-- 通过p名称空间给属性赋值 -->
<bean id="book002" class="com.bottom.ioc.Book" p:bookName="PHP是全世界最好的语言" p:price="96"/>
  1. 属性级联
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>
  1. 数组或集合类型的属性
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>
  1. 集合类型的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的生命周期(重要)

  1. IOC容器中的bean实例默认是单例的;
  2. 单例的实例是在容器创建的时候就产生了;多例是在要使用时才会产生。
  3. BeanPostProcessor-Bean后置处理器 如果在bean实例初始化的前后有需要做的事情,我们可以使用后置处理器实现
相关推荐
M1A119 小时前
小红书重磅升级!公众号文章一键导入,深度内容轻松入驻
后端
0wioiw020 小时前
Go基础(④指针)
开发语言·后端·golang
DKPT21 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
李姆斯1 天前
复盘上瘾症:到底什么时候该“复盘”,什么时候不需要“复盘”
前端·后端·团队管理
javachen__1 天前
Spring Boot配置error日志发送至企业微信
spring boot·后端·企业微信
seabirdssss1 天前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续1 天前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
OC溥哥9991 天前
Flask论坛与个人中心页面开发教程完整详细版
后端·python·flask·html
Volunteer Technology1 天前
三高项目-缓存设计
java·spring·缓存·高并发·高可用·高数据量
迷知悟道1 天前
java面向对象四大核心特征之抽象---超详细(保姆级)
java·后端