暑期自学 Day 16 | Spring (二)

控制反转 (IoC)

如果直接使用 new 来创建对象,那么应用和资源是直接创建联系的。如果使用工厂模式,工厂会提供相应的对象资源给应用,降低了程序间的耦合。

  • 只能降低耦合,并不能完全消除。
  • 把创建对象的权利交给了框架。*

使用 spring 实现控制反转

  • 创建一个maven项目,并添加依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>spring.selflearning</groupId>
    <artifactId>day01_eesy_03spring</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
        </dependency>
    </dependencies>


</project>
  • 创建配置文件
    在这个配置文件里写入可重用组件的id

resources/bean.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">
<!--  对象创建交给spring  -->
    <bean id="accountService" class="spring.selflearning.service.impl.AccountServiceImpl"></bean>
    <bean id="accountDao" class="spring.selflearning.dao.impl.AccountDaoImpl"></bean>
</beans>
  • 表现层利用spring创建IoC容器,获取所需对象
package spring.selflearning.ui;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.selflearning.dao.IAccountDao;
import spring.selflearning.service.IAccountService;
import spring.selflearning.service.impl.AccountServiceImpl;

/*
模拟表现层,用于调用业务层
 */

/*
获取Spring 的 IoC 核心容器,并根据id获取对象
 */
public class Client {
    public static void main(String[] args) {

        // 获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

        // 根据id获取bean对象
        IAccountService as = (IAccountService) ac.getBean("accountService");
        IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);
        System.out.println(as);
        System.out.println(adao);
        as.saveAccount();
    }
}

ApplicationContext

三个常用实现类

  • ClassPathXmlApplicationContext

    • 加载类路径下的配置文件
    • 实际开发中推荐使用这个
  • FileSystemXmlApplicationContext

    • 加载磁盘任意路径下的配置文件
  • AnnotationConfigApplicationContext

    • 用于读取注解创建容器

ApplicationContext 与 BeanFactory 的区别

  • ApplicationContext 创建核心容器时,在读取完配置文件内容后立即创建配置文件中的配置对象
    • 创建单例对象时适用
  • BeanFactory 创建核心容器时,延迟加载创建对象,即使用getBean()根据id获取对象时才创建对象
    • 创建多例对象时适用

创建bean对象的三种方式

bean.xml文件中,我们使用<bean></bean>标签来配置对象的id和class属性。
这是第一种方式:

<bean id="accountService" class="spring.selflearning.service.impl.AccountServiceImpl"></bean>

直接使用这种方法配置要创建对象的属性,对象所属类中必须有默认的构造函数,否则无法正常创建对象。

有时在java内置的jar包里,或者在他人创建的类中,没有默认构造函数。这种情况下我们需要使用第二种方式,即先获取该类,再通过factory-beanfactory-method属性来创建所需的对象。

<!-- 这是一个模拟工厂类,可能存在于jar包中,也可能在他人创建的类中-->
<bean id="instanceFactory" class="spring.selflearning.factory.InstanceFactory"></bean>
<!-- 获取相应的工厂和工厂内要创建对象对应的方法-->
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

第三中方式用于创建静态工厂类静态方法的对象:
class中获取静态类,factory-method中定义静态方法。

    <bean id="accountService" class = "spring.selflearning.factory.StaticFactory" factory-method="getAccountService"></bean>
</beans>
Bean 的其他属性
  • scope: 作用范围
    • 取值:singleton, prototype, request, session, global-session
  • bean 对象生命周期
    • singleton: 和容器相同
    • prototype: 对象创建是开始,对象长时间不用时,由Java垃圾回收器回收。
  • inti-method:对象初始化
  • destory-method:对象销毁
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

这文章要是在 Spring 板块发,交流起来会更好。

3年前 评论
Borris (楼主) 3年前
Galois (作者) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!