一、IOC

本文详细介绍了Spring框架的核心组件IOC(控制反转),包括其原理、BeanFactory和ApplicationContext的区别、Bean的管理方式、不同作用域的解析、生命周期管理、自动装配以及外部属性文件的引入。此外,还讲解了基于XML的Bean配置,如对象创建、属性注入、集合注入等,并通过实例展示了如何使用Spring进行对象初始化和销毁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、IOC

1、Spring框架介绍
  1. Spring是轻量级的开源的javaEE框架
  2. Spring有两个核心部分: IOC 和 AOP
    1. IOC : 控制反转,把创建对象的过程交给Spring进行管理
    2. AOP: 面向切面,不修改源代码进行功能增强
  3. Spring特点:
    1. 方便解耦,简化开发
    2. AOP编程支持
    3. 方便程序测试
    4. 方便和其他框架进行整合
    5. 方便进行事务操作
    6. 降低API开发难度
2、导入Spring相关jar包
    <dependencies>
<!--        日志包,并不是Spring中的-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
    </dependencies>
3、IOC容器底层原理
  1. 什么是IOC
    1. 控制反转,把对象创建和对象之间的调用过程交给Spring进行管理
    2. 使用IOC的目的就是降低耦合度
  2. IOC底层原理
    1. 通过xml解析读取xml配置文件中配置的bean标签,获取到配置的全类名
    2. Bean工厂类通过反射Class.forName(全类名)创建Class的对象
    3. 通过一个Bean工厂类将对象返回,完成对象的创建
4、IOC(BeanFactory接口)
  1. IOC思想基于IOC容器完成,IOC容器底层就是一个对象工厂

  2. Spring提供IOC容器有两种基本方式(两个接口)

    1. BeanFactory:IOC的基本实现,Spring内部使用的接口,开发人员不建议使用
      • 特点:加载配置文件的时候不会创建对象,在获取对象(getBean())才会创建对象
    2. ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,开发人员使用
      • 特点:加载配置文件的时候就会把在配置文件中的对象进行创建
  3. 继承树
    IOC容器继承树

5、IOC操作Bean管理
  1. Bean管理是指两个操作
    • Spring创建对象
    • Spring为对象注入属性
  2. Bean管理有两种方式
    • 基于xml配置文件方式实现
    • 基于注解方式实现
6、基于xml方式的Bean管理
  1. 创建对象: 在spring的配置文件中使用bean标签,默认调用的是类的无参构造器

    <bean id="user" class="day01.domain.User"></bean>
    
  2. 注入属性:两种方式注入属性

    1. 使用通过setter方法注入属性,要求类必须提供setter方法

      <!--    使用setter注入-->
          <bean id="bookSet" class="day01.domain.Book">
              <property name="name" value="三字经"></property>
              <property name="price" value="23"></property>
          </bean>
      
    2. 通过constructor构造器注入属性,此时不再调用类的无参构造器,创建对象

      <!--    使用构造器注入-->
          <bean id="bookCon" class="day01.domain.Book">
              <constructor-arg name="name" value="史记"></constructor-arg>
              <constructor-arg name="price" value="34"></constructor-arg>
          </bean>
      
    3. p命名空间注入,本质上还是setter方法注入,不做解释

  3. 如何给属性注入null等特殊符号

    1. 注入null值

      <!--    如何给对象注入特殊符号 可以给属性赋一个null值 null标签-->
          <bean id="bookSpecial" class="day01.domain.Book">
              <property name="name">
                  <null/>
              </property>
          </bean>
      
    2. 注入特殊符号

      <!--    如何给对象注入 <南京> 这样的字样:
                  方式一:使用转义字符 &gt; &lt;
                  方式二:使用 <![CDATA[<南京>]]>
              -->
          <bean id="bookSpec" class="day01.domain.Book">
      <!--        <property name="name" value="&lt;南京&gt;"></property>-->
              <property name="name">
                  <value><![CDATA[<南京>]]></value>
              </property>
          </bean>
      
  4. 如何注入外部bean

    1. 使用ref进行注入

      <!--    Service层对象的创建-->
          <bean id="userService" class="day01.service.impl.UserServiceImpl">
              <property name="userDao" ref="userDao"></property>
          </bean>
      <!--    Dao层对象的创建-->
          <bean id="userDao" class="day01.dao.impl.UserDaoImpl"></bean>
      
    2. 使用内部bean注入

      <!--    对于对象的注入不仅可以使用ref属性,也可以使用内部bean的方式-->
          <bean id="emp" class="day01.domain.Emp">
              <property name="name" value="Lucy"></property>
              <property name="gender" value=""></property>
              <property name="dept">
                  <bean class="day01.domain.Dept">
                      <property name="name" value="科创部"></property>
                  </bean>
              </property>
          </bean>
      
    3. 使用级联注入

  5. 集合类型怎么注入

    <!--    集合类型的注入-->
        <bean id="stu" class="day01.domain.Student">
            <property name="arr">
                <array>
                    <value>数组1</value>
                    <value>数组2</value>
                </array>
            </property>
            <property name="list">
                <list>
                    <ref bean="book1"></ref>
                    <ref bean="book2"></ref>
                    <ref bean="book3"></ref>
                </list>
            </property>
            <property name="map">
                <map>
                    <entry key="key1" value="value1"></entry>
                    <entry key="key2" value="value2"></entry>
                </map>
            </property>
            <property name="set">
                <set>
                    <value>set1</value>
                    <value>set2</value>
                    <value>set3</value>
                </set>
            </property>
        </bean>
        <bean id="book1" class="day01.domain.Book">
            <property name="name" value="java"></property>
            <property name="price" value="23"></property>
        </bean>
        <bean id="book2" class="day01.domain.Book">
            <property name="name" value="java"></property>
            <property name="price" value="23"></property>
        </bean>
        <bean id="book3" class="day01.domain.Book">
            <property name="name" value="java"></property>
            <property name="price" value="23"></property>
        </bean>
    
7、Spring中Bean的类型
  • 普通bean:在配置文件中定义bean类型就是返回类型,上面的都是普通bean

  • 工厂bean(FactoryBean) : 通过配置工厂,返回工厂要返回的类型

    • 实现步骤:

      1. 创建类,让这个类实现FactoryBean接口,重写getObject()方法,指定返回的对象

        public class CourseFactory implements FactoryBean<Course> {
            @Override
            public Course getObject() throws Exception {
                Course course = new Course();
                course.setName("一本书");
                return course;
            }
            @Override
            public Class<?> getObjectType() {
                return null;
            }
            @Override
            public boolean isSingleton() {
                return false;
            }
        }
        
      2. 在配置文件中配置工厂类

        <bean id="bean" class="day01.factorybean.CourseFactory"></bean>
        
      3. 测试

            @Test
            public void test1(){
                ApplicationContext context = 
                    new ClassPathXmlApplicationContext("application.xml");
                Course bean = context.getBean("bean", Course.class);
                System.out.println(bean);
            }
        
8、Spring中Bean的作用域(scope属性)
scope属性值作用域解释
scope=“singleton”默认值,bean在容器中是单例的
scope=“prototype”bean在容器中是原形的,即是多例的
scope=“request”一次请求间bean的单例的,很少使用
scope=“session”一次会话间bean是单例的,很少使用
  • singleton 和 prototype的区别?
    1. singleton 是单例的 prototype是多例的
    2. scope的属性值为singleton时,在加载Spring配置文件的时候就会创建实例对象,而设置scope的属性值为prototype时,在调用getBean()方法时才创建对象
9、Bean的生命周期
  1. 第一步:调用无参构造器
  2. 第二步:调用setter方法注入属性
  3. 第三步:我在bean初始化方法前执行,Bean的后置处理器postProcessBeforeInitialization()方法
  4. 第四步:调用初始化方法,需要配置
  5. 第五步:我在bean初始化方法后执行,bean的后置处理器postProcessAfterInitialization()方法
  6. 第六步:bean正在被使用
  7. 第七步:调用销毁方法,需要配置
<!--    配置bean初始化方法和销毁方法需要配置-->
    <bean id="lifeBean" class="day01.domain.LifeBean" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="生命周期"></property>
    </bean>
<!--    bean的后置处理器默认是BeanPostProcessor,要看到效果我们需要自己编写后置处理器实现BeanPostProcessor接口,并配置-->
    <bean id="beanPost" class="day01.domain.BeanPost"></bean>
public class LifeBean {
    private String name;
    public LifeBean() {
        System.out.println("第一步:调用无参构造器");
    }
    public void setName(String name) {
        System.out.println("第二步:调用setter方法注入属性");
        this.name = name;
    }
    public void initMethod(){
        System.out.println("第四步:调用初始化方法,需要配置");
    }
    public void userBean(){
        System.out.println("第六步:bean正在被使用");
    }
    public void destroyMethod(){
        System.out.println("第七步:调用销毁方法,需要配置");
    }
}

后置处理器BeanPost

public class BeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第三步:我在bean初始化方法前执行,Bean的后置处理器");
        return null;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步:我在bean初始化方法后执行,bean的后置处理器");
        return null;
    }
}

测试

    /**
     * 测试bean的生命周期
     */
    @Test
    public void test2(){
        ClassPathXmlApplicationContext context = 
            new ClassPathXmlApplicationContext("application.xml");
        LifeBean life = context.getBean("lifeBean", LifeBean.class);
        life.userBean();
        //关闭容器时bean被销毁
        context.close();
    }
10、基于xml的自动装配
  • bean中有一个属性为autowire完整自动装配属性值指定装配规则
    • 属性值为byName : 根据属性名称自动装配
    • 属性值为byType : 根据属性类型自动装配
11、基于xml引入外部属性文件
  • 以druid数据库连接池为例

    • druid.properties

      driverClassName=com.mysql.jdbc.Driver
      url=jdbc:mysql://127.0.0.1:3306/mnyuansql
      username=root
      password=1234
      
    • application.xml 要引入context命名空间

      <?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 name="url" value="${url}"/>
              <property name="username" value="${username}"/>
              <property name="password" value="${password}"/>
          </bean>
      </beans>
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值