🌐 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实例初始化的前后有需要做的事情,我们可以使用后置处理器实现
相关推荐
敲代码娶不了六花1 小时前
jsp | servlet | spring forEach读取不了对象List
java·spring·servlet·tomcat·list·jsp
2401_882727574 小时前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·前端框架
追逐时光者4 小时前
.NET 在 Visual Studio 中的高效编程技巧集
后端·.net·visual studio
大梦百万秋5 小时前
Spring Boot实战:构建一个简单的RESTful API
spring boot·后端·restful
斌斌_____5 小时前
Spring Boot 配置文件的加载顺序
java·spring boot·后端
路在脚下@6 小时前
Spring如何处理循环依赖
java·后端·spring
丁总学Java6 小时前
--spring.profiles.active=prod
java·spring
海绵波波1076 小时前
flask后端开发(1):第一个Flask项目
后端·python·flask
weisian1517 小时前
Redis篇--常见问题篇8--缓存一致性3(注解式缓存Spring Cache)
redis·spring·缓存
小奏技术7 小时前
RocketMQ结合源码告诉你消息量大为啥不需要手动压缩消息
后端·消息队列