Spring

1.Spring IoC的概念

1.1 Spring IoC概述

控制反转IoC是一种通过描述(在Java中可以是XML或者注解)并通过第三方(Spring提供的IoC容器)去产生或获取特定对象的方式。

在Spring中实现IoC(控制反转)的是IoC容器,其实现方式是依赖注入(Dependency Injection, DI).

控制反转最大的好处在于降低对象之间的耦合,当需要使用一个对象的时候,关于如何创造这个对象我们并不关心(创造对象由IoC容器来实现),我们只需要给出这个对象的描述信息,即可通过IoC容器获取这个对象。

 

1.2 Spring IoC容器

1.2.1 Spring IoC容器的设计

Spring IoC容器的设计主要是基于 BeanFactoryApplicationContext两个接口,其中ApplicationContext是BeanFactory的子接口之一, 其中BeanFactory是Spirng IoC容器所定义的最顶层的接口,而ApplicationContext是其子接口之一,并且对BeanFactory功能做了许多有用的扩展,所以在绝大部分工作场景下,都会使用ApplicationContext作为Spring IoC容器。

ClassPathXmlApplicationContext是ApplicationContext接口的实现类,我们可以用它去实例化ApplicationContext接口

示例:

Bean的描述信息(XML方式,存储在applicationContext.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"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <!--声明bean-->
   <!--
      DI:给属性赋值
      简单类型: java中的基本数据类型和String

      1. set注入: spring调用类的set方法,通过set方法完成属性赋值
         简单类型的set注入:
         语法: <bean id="xxx" class="yyy">
                  <property name="属性名" value="简单类型属性值"/>
                  ...
               </bean>

   -->
   <!--简单类型set注入-->
   <bean id="myStudent" class="com.bjpowernode.ba01.Student">
       <property name="name" value="李四"/><!--setName("李四")-->
       <property name="age" value="22" /><!--setAge(22)-->
       <property name="email" value="lisi@qq.com" /><!--setEmail("xxx)-->
   </bean>

   <!--声明日期类-->
   <bean id="mydate" class="java.util.Date">
       <property name="time" value="933295249276"/><!--setTime()-->
   </bean>
</beans>

通过ClassPathXmlApplicationContext实例化ApplicationContext并获取Bean

String config="applicationContext.xml";
ApplicationContext ctx  = new ClassPathXmlApplicationContext(config);
Student student = (Student) ctx.getBean("myStudent");
System.out.println("student="+student);
Date date = (Date) ctx.getBean("mydate");
System.out.println("date==="+date);

 

1.2.2 Spring IoC容器的初始化和依赖注入

1.2.3 Spring Bean的生命周期

 

2. 装配Spring Bean

2.1依赖注入的三种方式

注意依赖注入不等于XML配置,下面用XML方式只是举例注入类型,例如注解也能用setter注入,依赖注入的三种方式只是设计原理,装配Bean的时候用的不同的方法都是基于这三种依赖注入方式的

  • 构造器注入

    Spring采用反射的方式通过使用类的构造方法来完成注入,这就是构造器注入的原理

    package com.ssm.chapter10.pojo;

    public class Role {
    private Long id;
    private String roleName;
    private String note;
       
    public Role(String roleName, String note) {
    this.roleName = roleName;
    this.note = note;
    }
    /****setter and getter****/

    }
    <bean id="role1" class="com.ssm.chapter10.pojo.Role">
       <constructor-arg index="0" value="总经理"/>
       <constructor-arg index="1" value="公司管理者"/>
    </bean>

    constructor-arg元素用于定义类构造方法的参数,index用于 定义参数的位置,value则是设置值

    参数比较多的时候,构造器注入的可读性比较差,这时候应该考虑使用setter注入

  • setter注入

    setter注入的原理是通过反射调用类的无参构造方法得到一个对象(因此这个类必须有一个无参的构造方法),然后再通过set方法往对象中注入值。

    package com.ssm.chapter10.pojo;

    public class Role {
    private Long id;
    private String roleName;
    private String note;

    public Role() {
    }

    public Role(String roleName, String note) {
    this.roleName = roleName;
    this.note = note;
    }
    /****setter and getter****/

    }
    <bean id="role2" class="com.ssm.chapter10.pojo.Role">
       <property name="roleName" value="高级工程师"/>
       <property name="note" value="重要人员"/>
    </bean>
  • 接口注入

    有时候有些资源并非来源于自身系统,而是来源于外界,这个时候使用接口注入(留个坑,详细信息请google)

     

2.2 装配Bean

Spring中提供了3种方法进行配置Bean,在实际开发中,这三种配置方式都会用到,并且常常混用,因此必须有一个优先级,其优先级从上到下一次递增

  • 在XML中显示配置

  • 在Java的接口和类中实现配置

  • 隐式Bean的发现机制和自动装配原则

第二种和第三种方式对应的就是注解的方式

2.2.1 在XML中显示配置

public class ComplexAssembly{
   private Long id;
   private List<String> list;
   private Map<String,String> map;
   private Properties props;
   private Set<String> set;
   private String[] array;
   /****setter and getter****/
}

 

<?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-4.0.xsd">
   <!--很明显这里的装配用的 是构造器注入的方式-->
   <!--简易装配,用于装配基础类型和String类型-->
<bean id="role_1" class="com.ssm.chapter9.pojo.Role">
<property name="roleName" value="高级工程师" />
<property name="note" value="重要人员" />
</bean>

<bean id="role_2" class="com.ssm.chapter9.pojo.Role">
<property name="id" value="1" />
<property name="roleName" value="高级工程师" />
<property name="note" value="重要人员" />
</bean>
<bean id="source" class="com.ssm.chapter9.pojo.Source">
<property name="fruit" value="橙汁" />
<property name="sugar" value="少糖" />
<property name="size" value="大杯" />
</bean>

   <!--ref用于装配引用类型,其值是之前定义的Bean的id-->
<bean id="juiceMaker2" class="com.ssm.chapter9.pojo.JuiceMaker2">
<property name="beverageShop" value="贡茶" />
<property name="source" ref="source" />
</bean>

   <!--装配集合-->
<bean id="complexAssembly" class="com.ssm.chapter10.pojo.ComplexAssembly">
<property name="id" value="1" />
<property name="list">
<list>
<value>value-list-1</value>
<value>value-list-2</value>
<value>value-list-3</value>
</list>
</property>
<property name="map">
<map>
<entry key="key1" value="value-key-1" />
<entry key="key2" value="value-key-2" />
<entry key="key3" value="value-key-3" />
</map>
</property>
<property name="props">
<props>
<prop key="prop1">value-prop-1</prop>
<prop key="prop2">value-prop-2</prop>
<prop key="prop3">value-prop-3</prop>
</props>
</property>
<property name="set">
<set>
<value>value-set-1</value>
<value>value-set-2</value>
<value>value-set-3</value>
</set>
</property>
<property name="array">
<array>
<value>value-array-1</value>
<value>value-array-2</value>
<value>value-array-3</value>
</array>
</property>
</bean>
</beans>

 

如果集合中的元素类型是引用类型(除了String)

public class UserRoleAssembly{
private Long id;
private List<Role> list;
private Map<Role,User> map;
private Set<Role> set;
/****setter and getter****/
}

 

<?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-4.0.xsd">

<bean id="role1" class="com.ssm.chapter10.pojo.Role">
<property name="id" value="1" />
<property name="roleName" value="role_name_1" />
<property name="note" value="role_note_1" />
</bean>

<bean id="role2" class="com.ssm.chapter10.pojo.Role">
<property name="id" value="2" />
<property name="roleName" value="role_name_2" />
<property name="note" value="role_note_2" />
</bean>

<bean id="user1" class="com.ssm.chapter10.pojo.User">
<property name="id" value="1" />
<property name="userName" value="user_name_1" />
<property name="note" value="role_note_1" />
</bean>

<bean id="user2" class="com.ssm.chapter10.pojo.User">
<property name="id" value="2" />
<property name="userName" value="user_name_2" />
<property name="note" value="role_note_1" />
</bean>

<bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly">
<property name="id" value="1" />
<property name="list">
<list>
<ref bean="role1" />
<ref bean="role2" />
</list>
</property>
<property name="map">
<map>
<entry key-ref="role1" value-ref="user1" />
<entry key-ref="role2" value-ref="user2" />
</map>
</property>
<property name="set">
<set>
<ref bean="role1" />
<ref bean="role2" />
</set>
</property>
</bean>
</beans>

2.2.2 通过注解配置Bean

通常不推荐使用XML的方式装配,而推荐使用注解的方式装配Bean.

 

通常,当配置的类式自己正在开发的工程,那么应该考虑Java配置为主(即2、3两种,优先用3);如果配置的类并不是自己开发的,建议用1

 

posted @ 2021-08-16 00:05  9761滴  阅读(13)  评论(0编辑  收藏  举报