Spring框架,Spring IoC控制反转

一、Spring框架

  • Spring框架中核心内容:IoC控制反转、AOP面向切面编程。
  • Spring框架的核心功能是:维护对象之间的依赖关系。
  • 传统的Java编程方式,是通过new对象来进行对象的创建和维护的;Spring是通过容器的方式来维护对象的,Spring会根据配置文件以反射的方式进行对象的创建,之后将创建的对象放入到Spring容器当中,在使用的时候,通过beanId等多种方式来获取对应的对象。
  • Spring解决的具有代码问题:Java SE中通过new方法来创建具体的对象,代码中存在大量的new对象,这种调用方式属于硬编码,维护改造十分不方便,为了简化Java代码开发,方便快捷的管理使用Java对象,Spring引入了容器概念,以依赖注入的方式管理容器中众多的Java对象。

二、Spring基础配置文件

Spring以xml格式的配置文件来进行容器整体的配置管理。
Spring配置文件:

<?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:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
       >

</beans>

Spring配置文件的几种读取方式:

//1. 编译路径classpath根目录读取,以Spring配置上下文的方式读取
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

//2. 编译路径classpath根目录读取,以普通xml文件资源来读取,再将读取的文件资源转化为spring bean工厂对象
Resource resource = new ClassPathResource("spring-config.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);

//3. 以文件系统路径来读取
ApplicationContext appfactory = new FileSystemXmlApplicationContext("F:/yingcaiTestModel/spring/spring-config.xml");

三、Spring IoC/DI

  1. Spring IoC:Inversion of Control,(IC大写o小写)控制反转,这是Spring Framework框架的核心思想,是一种设计模式,几乎贯穿整个生态圈,所谓IoC,对于Spring框架来说,就是由Spring容器来负责控制对象的生命周期和对象间的依赖关系。
  • 通俗的说,IoC提倡的做法为:系统中所有的类都会在Spring容器中登记,告诉Spring你是个什么东西,你需要什么东西,然后Spring会在系统运行到适当的时候,把你要的东西给你,同时也是把你交给其他需要你的东西。所有的类的创建、销毁都是由Spring来控制,也就是说控制对象生命周期不再是引用他的对象,而是Spring容器,对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被Spring容器控制,所以这叫控制反转。
  1. DI:Dependency Injection,依赖注入,在Spring的内部IoC的设计模式通过依赖注入的技术来具体实现,对象之间依赖关系由容器在运行期决定,形象地说,即由容器动态的将某个依赖对象注入到目标对象之中,依赖注入的目的并非为软件系统带来更多功能,而是为了提升对象重用的频率,并未系统搭建一个灵活、可扩展的平台。
  • 通俗地说,我们告诉Spring容器,某个类需要注入哪些类型的属性,这个类的具体实例化过程以及销毁过程我们完全不关心,交给Spring容器帮助我们装配对象、销毁对象,这就是依赖注入。
  1. IoC与DI的区别与联系:
  • 控制反转是一种思想:是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦。
  • 依赖注入是一种设计模式:将实例变量传入到一个对象中去。
  • IoC框架使用依赖注入作为实现控制反转的方式

四、 Bean对象的注入方式

  1. 属性注入:
<bean id="manageInfo" class="com.yingcai.model.ManageInfo">
    <property name="level" value="1"/>
    <property name="role" value="supermanager"/>
</bean>

<bean id="userInfo" class="com.yingcai.model.UserInfo">
    <property name="id"  value="1" />
    <property name="name" value="zhoujy"/>
    <property name="age" value="18"/>
    <property name="sex" value="man"/>
    <property name="manageInfo" ref="manageInfo"/>
    <property name="hobbyList">
        <list>
            <value>1</value>
            <value>2</value>
            <value>3</value>
            <value>4</value>
            <value>5</value>
        </list>
    </property>
    <property name="otherInfo">
        <map>
            <entry key="1" value="111"/>
            <entry key="2" value-ref="manageInfo"/>
        </map>
    </property>
</bean>
  1. 构造器注入:
<bean id="userInfo1" class="com.yingcai.model.UserInfo">
    <constructor-arg name="id" type="java.lang.Integer" value="1"/>
    <constructor-arg name="name" type="java.lang.String" value="zhoujy"/>
    <constructor-arg name="age" value="18"/>
    <constructor-arg name="sex" value="man"/>
    <constructor-arg name="manageInfo" ref="manageInfo"/>
    <constructor-arg name="hobbyList" type="java.util.List">
        <list>
            <value>1</value>
            <value>1</value>
            <value>1</value>
            <value>1</value>
        </list>
    </constructor-arg>
    <constructor-arg name="otherInfo" type="java.util.Map">
        <map>
            <entry key="1" value="111"/>
            <entry key="2" value-ref="manageInfo"/>
        </map>
    </constructor-arg>
</bean>

五、Bean对象的作用域

Spring应用启动时,会默认实例化配置文件中声明的Bean对象,每个声明的Bean对象都只实例化一次,这就意味着Spring容器中的对象有且只有一个,虽然我们可以通过代码的方式获取对象后进行对象属性的修改,但在特殊系统场景下,这种硬编码的方式显然不能满足实际的场景需求,因此Spring引入了作用域的概念,当然,对于数据库连接的管理简单使用作用域来解决是根本不行的,企业系统中通常使用连接池技术来解决。Bean对象作用域的配置使用bean标签的scope属性来指定。

作用域 描述
singleton 单例模式,在一个Spring容器中只会实例化一个Bean对象,该配置为Spring默认配置。
prototype 多例模式,允许Bean对象实例化多次,每次调用时都重新创建一个新的对象。
request 在一次HTTP请求中,实例化一次Bean对象。
session 在一个HTTP Session域中,实例化一次Bean对象。
globalSession 在一个全局HTTP Session域中,实例化一次Bean对象。所谓的全局session与portlet模式有关,在单点登录中涉及。

六、Bean对象的懒加载

Spring应用启动时,不管系统是否对对象进行调用,容器都会将配置文件中的Bean进行实例化,在一定程度上会造成容器资源的浪费,因此,Spring提供了一种Bean对象懒加载的方式。
通过使用bean标签的lazy-init属性来进行配置,懒加载模式默认为false。

  • 当scope=”singleton”,lazy-init=”false”时,Spring容器启动时就会实例化对象。
  • 当scope=”singleton”,lazy-init=”true”时,Spring容器启动时不会实例化对象,在第一次调用对象时才进行实例化过程。
  • 当scope=”prototype”时,懒加载将失去作用,每次调用对象时都重新实例化一个对象。

七、IoC配置极简化

在现实系统中,应用中的Bean对象存在成千上万,而且互相之间存在复杂的依赖关系,如果单纯的使用XML文件进行Bean对象的装配,这样的工作还是相当复杂与繁琐,容易出错,因此Spring提供了Bean对象的自动装配策略与注解方式来简化Spring Bean的配置装配过程

1. Bean的自动装配

通过使用bean标签的autowire属性来配置Bean对象的自动装配策略,Spring提供了五种自动装配策略:

装配策略 描述
no 不采用autowire机制.。这种情况,当我们需要使用依赖注入,只能用ref标签。
byName 通过名称进行装配,把与当前Bean对象属性名称相同的其他Bean对象自动装配到当前Bean对象属性中。
byType 通过类的类型进行装配,把与当前Bean对象属性类型一致的其他Bean对象自动装配到当前Bean对象属性中。通过byType进行自动装配时,要求匹配类型的对象只存在一个,如果存在多个适配的对象时,会主动抛出异常。
constructor 通过类的构造器进行类型匹配进行装配,使用构造器进行装配,把与当前Bean对象构造器入参具有相同类型的其他Bean对象装配到当前Bean对象属性中。
autodetect 自适应装配,首先尝试使用constructor进行自动装配,如果失败,再尝试使用byType进行自动装配。高版本已经不支持该属性的配置。
default 采用父级标签(即beans的default-autowire属性)的配置。
  • 全局配置默认自动装配策略:
    在Spring配置头中加入default-autowire = "byType"
    Bean标签不使用autowire属性时,表示不自动装配,既选择no策略

2. 使用注解进行Bean装配

  • 注解的方式是将XML配置文件中的标签以注解标记的方式融入到代码中,在编写代码的过程中进行对象依赖管理,在Spring容器启动时,让容器根据注解来进行对象的装配实例化。
  • Spring容器默认关闭注解装配模式,开启注释装配模式的标签:
<!-- 指定扫描包下的所有类中的注解 -->
<!-- 扫描包时,会扫描指定包下的所有子孙包 -->
<!-- 这里的路径必须有初始路径 -->
<context:component-scan base-package="com.**" />

消除XML配文文件中的bean标签配置

  • @Configuration注解:标注于类上,将一个类声明为配置域,一个配置域中可以声明多个配置对象,这些配置对象都会加载进Spring容器中。
  • @Bean注解:标注于方法上,该方法必须存在返回值,该返回值即为该配置中的一个对象,该对象的BeanId默认为方法名称
  • @Component注解:标注于类上,将一个类声明为Spring Bean,并加入到Spring容器当中去,默认的BeanId为类名的无限定名称,也可以主动声明BeanId

Bean属性装配注解

  • 简单值属性装配注解:Spring @Value注解
  • 依赖对象属性装配注解:Spring自带@Autowired注解
    JSR-250规范的@Resource注解

Spring Test与JUnit单元测试

//JUnit启动类注解,这里的启动类是Spring Test测试的启动类
@RunWith(SpringJUnit4ClassRunner.class)
//加载Spring容器配置文件
@ContextConfiguration(locations = {"classpath:spring-config.xml"})
public class SpringBaseTest {
    @Autowired
    private ManageInfo manageInfo;

    //测试启动方法
    @Test
    public void test(){
        System.out.println(manageInfo.toString());
    }
}
posted @ 2020-11-23 21:03  逍遥客灬  阅读(236)  评论(0编辑  收藏  举报