• Spring-IOC


    Spring-IOC

    一、什么是IOC?

    • Ioc即Inverse of Control,中文为控制反转。
    • 在Spring中,创建对象的工作不再由应用程序(程序员主动的使用new关键字)主动完成,而是由Spring容器负责创建,然后注入给应用程序,由Spring来管理应用程序中的所有对象及其依赖关系。
    • 通俗说就是程序员在代码中无需使用new关键字来创建对象,创建对象的任务交给了Spring。然后Spring根据xml中配置的属性,将其注入到对象中。(创建对象并赋值

    二. 实例化 Spring IoC 容器

    Spring 核心容器的理论很简单:Spring 核心容器就是一个超级大工厂,所有的对象都会被当成 Spring 核心容器管理的对象

    你必须实例化 Spring IoC 容器,读取其配置文件来创建 Bean 实例。然后你可以从 Spring IoC 容器中得到可用的 Bean 实例。

    BeanFactory
    └── ApplicationContext
        └── ClassPathXmlApplicationContext
    

    Spring IoC 容器主要是基于 BeanFactoryApplicationContext 两个接口:

    • BeanFactory 是 Spring IoC 容器的顶层接口
    • ApplicationContext 是最常用接口
    • ClassPathXmlApplicationContext 是 ApplicationContext 的实现类。顾名思义,它从 classpath 中加载一个 XML 配置文件,构建一个应用程序上下文。你也可以指定多个配置文件。

    BeanFactory 接口定义了 Spring IoC 整个体系中中最重要的方法(簇):getBean() 方法。这个方法用于从 Spring IoC 容器中获得 Bean 。

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    ApplicationContext context = new ClassPathXmlApplicationContext("service.xml", "dao.xml");
    

    在获得应用程序上下文(也就是IoC容器)后,你只需要调用 getBean() 方法并传入唯一的 Bean ID/名称和 Bean 的 Class 对象,就可以获得容器中的 Bean。

    Human tom = context.getBean("tom", Human.class);
    

    三、Spring创建Bean

    Spring可以帮你创建、管理Bean对象,但你需要“告诉”它要创建、管理哪些对象。

    Spring允许你在一个(或者多个)xml配置文件中配置Bean,对于Spring容器,这些个配置文件就是它创建Bean对象的依据。

    一个Spring 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">
    
    </beans>
    

    多个Spring xml文件我们可以通过import标签进行导入,和多为一:

    <import resource="spring-dao.xml"/>
    

    创建 Bean 的方式常见三种:

    • 类自身的构造方法
    • 工厂类提供的工厂方法
    • 工厂对象提供的工厂方法

    1、使用类自身的构造方法

    每个 bean 都必须提供一个唯一的名称或id,以及一个完全限定的类名,用来让 Spring IoC 容器对其进行创建。Spring 通过类的构造方法来创建 Bean 对象。

    <beans ...>
        <bean id="xxx" class="xxx.xxx.Xxx"></bean>
    </beans>
    

    2、 使用工厂类提供的工厂方法

    <bean id="tom" class="工厂类" factory-method="工厂方法">
    </bean>
    

    3、 使用工厂对象提供的工厂方法

    <!-- 声明创建工厂对象 -->
    <bean id="factory" class="工厂类"/>
    
    <bean id="tom" factory-bean="工厂对象id" factory-method="工厂方法">
    </bean>
    

    四、Spring装配简单属性

    装配,即为 Bean 的属性进行 初始化 / 赋值。

    简单类型 是指: 基本数据类型、基本数据类型包装类 和 字符串 。

    装配方式有两种:

    • 通过 构造方法 装配
    • 通过 setter 装配

    1、 构造方法装配

    通过构造方法装配,即设置 Spring 通过调用有参构造方法(默认是调用无参构造方法)来创建对象。在 bean 元素内使用 constructor-arg 子元素,即可触发构造方法装配。

    <bean id="..." class="...">
        <constructor-arg index="x" value="xx"/>
        ...
    </bean>
    

    index 属性表示构造函数形参 索引(从0开始)。如果参数的类型具有唯一性,那么可以使用 type 属性,通过 参数类型 来指定构造方法和参数值。

    为了简化配置,Spring 提供了一个名为 c 的 schema,来简化配置。

    <beans xmlns="..."
           xmlns:xsi="..."
           xmlns:c="http://www.springframework.org/schema/c"
           xsi:schemaLocation="...">
    
        <bean id="..." class="..." c:_0="xxx" c:_1="xxx" ... />
    </beans>
    

    使用这种简写方式,完全不用出现 costructor-arg 子元素,只需在 bean 元素中多增加几个 c:_索引="参数值" 这样的属性。

    2、 setter 装配

    通过 setter 装配,即设置 Spring 在(通过无参构造方法)创建对象后,通过调用对象的属性的 setter 方法来为对象的属性赋值。在 bean 元素内使用 property 子元素,即可触发 setter 装配。

    <bean id="..." class="...">
        <property name="xxx" value="xxx" />
        ...
    </bean>
    

    property 元素的 name 属性用于指定对象的属性名,value 属性用于指定要设置值。

    为了简化配置,Spring 提供了一个名为 p 的 schema,来简化配置。

    <beans xmlns="..."
           xmlns:xsi="..."
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="...">
    
        <bean id="tom" class="com.hemiao.bean.Human" p:name="tom" p:age="20" />
    
        ...
    </beans>
    

    使用这种简写方式,完全不用出现 property 子元素,只需在 bean 元素中多增加几个 p:属性名="属性值" 这样的属性。

    五、Spring装配复杂属性

    更复杂的属性类型是集合类型(数组、List、Set、Map)属性。

    Bean 的属性可能远不止基本类型这么简单,还有可能是基本类型的集合(List、Set 和 Map)。这种情况下,属性的赋值不再是 property-value 这种结构,而是 property-list-value 三层结构。

    <bean id="..." class="...">
    
        <property name="数组属性名">
            <array>
                <value>xxx</value>
                ...
            </array>
        </property>
    
        <property name="List属性名">
            <list>
                <value>xxx</value>
                ...
            </list>
        </property>
    
        <property name="Set属性名">
            <set>
                <value>xxx</value>
                ...
            </set>
        </property>
    
        <property name="Map属性名">
            <map>
                <entry key="xxx" value="xx"/>
                ...
            </map>
        </property>
    
    </bean>
    

    如果集合是引用类型的集合,那么使用的子元素就从 value 改为 ref。map 使用的是 key-refvalue-ref

    <list>
        <ref bean="myDataSource" />
    </list>
    
    <set>
        <ref bean="myDataSource" />
    </set>
    
    <map>
        <entry key ="a ref" value-ref="myDataSource"/>
    </map>
    

    引用的集合还有一种简写形式

    <list>
        <ref class="类的完全限定名" />
    </list>
    
    <set>
        <ref class="类的完全限定名" />
    </set>
    
    <map>
        <entry key ="a ref" class="类的完全限定名"/>
    </map>
    

    六、 自动装配

    当一个 Bean 需要访问另一个 Bean 时,你可以显示指定引用装配它。不过,Spring IoC 容器提供自动装配功能,只需要在 beanautowire 属性中指定自动装配模式就可以了。

    装配模式 说明
    no 默认值。不执行自动装配。你必须显示地装配所依赖对象
    byName 以 Bean 的属性名为依据,装配一个与属性名同名的 Bean
    byType 以 Bean 的属性类型为依据,装配一个与之同类型的 Bean
    constructor 通过构造方法初始化 Bean 的属性,并依据参数的类型,装配一个与参数同类型的 Bean

    尽管自动装配很强大,但是代价是降低了 Bean 配置的可读性。在实践中,建议仅在依赖关系不复杂的应用中使用。

    七、注解代替XML配置

    component-scan标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Component、@Repository、@Service、@Controller标签的类自动注册到spring容器。对标记了 Spring's @Required、@Autowired、JSR250's @PostConstruct、@PreDestroy、@Resource、JAX-WS's @WebServiceRef、EJB3's @EJB、JPA's @PersistenceContext、@PersistenceUnit等注解的类进行对应的操作使注解生效(包含了annotation-config标签的作用)。

    关键是怎么获得通过扫描方式被spring容器管理的bean

    getBean的默认名称是类名(头字母小写),如果想自定义,可以@Service(“aaaaa”)这样来指定。
    这种bean默认是“singleton”的,如果想改变,可以使用@Scope(“prototype”)来改变。

    在 XML 配置文件中加上 <context:component-scan base-package="Bean所在的包路径"/> 即可开启 Spring 的自动扫描功能,这是使用注解替代XML配置的前提。

    1、 @Component 注解

    @Component 注解用于标注于 Bean 的类上。凡是被标注了该注解的类(只要在扫描路径下)都会被 Spring 创建。

    @Component 注解有唯一的属性 value 属性。它用来为 Bean 命名。同理它的语义化子注解也有

    @Component 注解有三个语义化的子注解:

    • @Repository(用于持久层)
    • @Service (用于业务层)
    • @Controller(用于 Web 层)

    2、@Value 注解

    @Value 注解用于标注于简单类型属性上。凡是被标注了该注解的属性都会被 Spring 注入值(赋值)。

    @Value 注解有唯一的属性 value 属性。它用来为简单属性指定值。

    3、@Autowired 注解

    @Autowired 注解用于标注于引用类型属性上。凡是被标注了该注解的属性都会被 Spring 以 类型 为依据注入另一个 Bean 的引用。

    @Autowired 注解有唯一的属性 required 属性(默认值为 true)。它用来指示该对该属性的注入是否为必须(默认必须),即,在 Spring IoC 容器中没有发现符合类型的其他Bean时,会抛出异常。

    4、@Qualifier 注解(配合@Autowired注解使用)

    @Qualifier 注解需要结合 @Autowired 注解使用。它用于标注于引用类型属性上。凡是被标注了该注解的属性都会被 Spring 以 名字 为依据注入另一个 Bean 的引用。

    @Qualifier 注解有唯一的属性 value 属性。它用于指示需要注入的另一个 Bean 的名字。

    5、@Resource 注解

    它是JDK自带的注解,它是@Autowired && @Qualifier两种注解的结合体

    默认先通过Bean的Id、名来寻找并注入,如果找不到就通过类型来注入

    八、Bean 的作用域

    默认情况下,Spring IoC 容器只会对一个 Bean 创建一个实例。即单例。Spring IoC 提供了 4 种 作用域,它决定了 Spring IoC 是否/何时 生成一个新的对象。常见有:

    • singleton(单例):默认值。在整个应用中,Spring 只为其生成一个 Bean 的实例。
    • prototype(原型):Spring 每次都会生成一个 Bean 的实例。

    在 XML 配置文件中, 通过 bean 元素的 scope 属性进行设置。该属性取值:singleton | prototype | 其他 。

    在 注解 配置中,使用 @Scope 注解,该注解标注于 Bean 的类上(常见于 @Component 之下)。该注解有唯一属性 value 属性,其取值有: singleton | prototype | 其他。

  • 相关阅读:
    代码:城市名称的联想下拉框。可按拼音搜索、按汉字搜索,是一种很简单的实现方式
    代码:拖拽
    插件:zTree
    代码:遍历
    学习笔记:Stage.js(又叫Cut.js)——2D canvas 开发库,游戏方面的
    前端模块化、构建工具
    二级联动下拉菜单
    thinkphp的目录结构设计经验总结
    tp 路径表示
    liunx 根目录介绍
  • 原文地址:https://www.cnblogs.com/whitespaces/p/12442422.html
Copyright © 2020-2023  润新知