Spring学习系列(一)--IoC容器

Spring学习系列(一)--IoC容器

1、什么是IoC容器和beans?

在回答题目中的问题之前,有必要回答什么是依赖。所谓依赖,简单来说,就是某个对象为了能向外部准确提供它的类所声明的服务,有时它必须与其他不同类型的对象合作,那么可以称这个对象依赖这些它与之合作的对象。

依赖注入则是通过构造函数的参数、工厂方法的参数或者是当实例从无参的构造函数或工厂方法返回后,在实例上设置属性完成的。完成依赖注入的主体称之为容器,由依赖注入的方式实例化的对象把控制权转移到了容器手上,造成了控制权反转的效果,所以称之为IoC容器

bean在Spring中只是一个名字,指那些构成应用程序的主干并且被IoC容器管理的对象。所谓管理,一般指实例化、配置或装配。beans以及beans之间的依赖反映在IoC容器的配置中。

2、容器概览

Spring容器的实现非常复杂,现阶段只需认识org.springframework.context.ApplicationContext这个接口就行,它既提供了一定层次的抽象,又提供了比较完备的功能。面向对象的知识告诉我们,抽象层次越高,对外暴露的接口就越少、越通用,抽象层次越低,接口就越丰富,越具体。ApplicationContext的抽象层次就很适中。

The Spring IoC container

3、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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

3.1、bean的命名

bean标签中的子标签idname都可以对bean命名。不同的是id至多给起一个名字,name可以起任意多个名字,名字之间用逗号、分号或空格分隔。

还可以在bean定义的外部起别名

<alias name="fromName" alias="toName"/>

3.2、bean的实例化

  1. class属性指定类的全限定名,调用类的构造方法实例化

  2. 静态工厂方法。class属性指定包含该方法的类,factory-method指定该静态方法

    <bean id="clientService"
        class="examples.ClientService"
        factory-method="createInstance"/>
    

4、依赖

4.1、依赖注入

  • 基于构造器

    基于构造器的依赖注入方法核心在于参数的解析,方式有3种

    • 类型匹配,type属性

      <bean id="exampleBean" class="examples.ExampleBean">
          <constructor-arg type="int" value="7500000"/>
          <constructor-arg type="java.lang.String" value="42"/>
      </bean>
      
    • 索引匹配,index属性

      <bean id="exampleBean" class="examples.ExampleBean">
          <constructor-arg index="0" value="7500000"/>
          <constructor-arg index="1" value="42"/>
      </bean>
      
    • 名字匹配,name属性

      <bean id="exampleBean" class="examples.ExampleBean">
          <constructor-arg name="years" value="7500000"/>
          <constructor-arg name="ultimateAnswer" value="42"/>
      </bean>
      
    • 基于setter方法

4.2、配置细节

4.2.1、Straight Values

property标签的value指定属性或构造器参数的字符串表示形式,spring负责把字符串解析为特定的类型,可以解析的类型包括Java原始类型或String类型。

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- results in a setDriverClassName(String) call -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="masterkaoli"/>
</bean>

value还可以配置java.util.Properties类型,spring可以自动解析

<bean id="mappings"
      class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">

    <!-- typed as a java.util.Properties -->
    <property name="properties">
        <value>
            jdbc.driver.className=com.mysql.jdbc.Driver
            jdbc.url=jdbc:mysql://localhost:3306/mydb
        </value>
    </property>
</bean>

4.2.2、指向其他bean的引用

ref标签

<ref bean="someBean"/>

4.2.3、集合

listsetmapprops标签对应Java集合类型中的ListSetMapProperties

<bean id="moreComplexObject" class="example.ComplexObject">
    <!-- results in a setAdminEmails(java.util.Properties) call -->
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@example.org</prop>
            <prop key="support">support@example.org</prop>
            <prop key="development">development@example.org</prop>
        </props>
    </property>
    <!-- results in a setSomeList(java.util.List) call -->
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
    <!-- results in a setSomeMap(java.util.Map) call -->
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
    <!-- results in a setSomeSet(java.util.Set) call -->
    <property name="someSet">
        <set>
            <value>just some string</value>
            <ref bean="myDataSource" />
        </set>
    </property>
</bean>

4.2.4、Null

<null/>

5、Bean Scope

单例

Singleton

原型

Prototype

6、基于注解的容器配置

6.1、@Autowired

  • 作用于构造器

    public class MovieRecommender {
    
        private final CustomerPreferenceDao customerPreferenceDao;
    
        @Autowired
        public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
            this.customerPreferenceDao = customerPreferenceDao;
        }
    
        // ...
    }
    
  • 作用于setter方法

    public class SimpleMovieLister {
    
        private MovieFinder movieFinder;
    
        @Autowired
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }
    
    }
    
  • 作用于有任意名字任意参数的方法

    public class MovieRecommender {
    
        private MovieCatalog movieCatalog;
    
        private CustomerPreferenceDao customerPreferenceDao;
    
        @Autowired
        public void prepare(MovieCatalog movieCatalog,
                CustomerPreferenceDao customerPreferenceDao) {
            this.movieCatalog = movieCatalog;
            this.customerPreferenceDao = customerPreferenceDao;
        }
    }
    
  • 作用于域和构造器

    public class MovieRecommender {
    
        private final CustomerPreferenceDao customerPreferenceDao;
    
        @Autowired
        private MovieCatalog movieCatalog;
    
        @Autowired
        public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
            this.customerPreferenceDao = customerPreferenceDao;
        }
    
        // ...
    }
    

6.2、@Resource

public class MovieRecommender {

    @Resource
    private CustomerPreferenceDao customerPreferenceDao;

    @Resource
    private ApplicationContext context; 

    public MovieRecommender() {
    }

    // ...
}

@Resource先ByName,后ByType

@Autowired先ByType,后ByName

posted @ 2020-06-06 13:33  中知  阅读(95)  评论(0)    收藏  举报