Spring IoC 配置元信息

195 阅读2分钟

1.大纲

Bean 定义配置

  1. 基于XML文件
  2. 基于Properties文件
  3. 基于Java注解
  4. 基于Java API (专题讨论)
  5. 基于Groovy DSL方式 IoC容器配置
  • 基于XML文件
  • 基于Java注解
  • 基于Java API 外部属性配置
  • 基于Java注解,如@Value

2. BeanFactory和ApplicationContext谁才是Spring IoC容器?

参考官方文档的说明 docs.spring.io/spring-fram…

// ApplicationContext 是BeanFactory的子类和实现
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection.xml");

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

ApplicationContext集成并组合了BeanFactory(又继承又组合,类似于代理的设计模式),是BeanFactory的超集。

2. BeanFactory和ApplicationContext使用场景?

BeanFactor是Spring底层的IoC容器

2.1 BeanFactor容器XML方式

dependency-lookup.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 = "user" class="ioc.User">
        <property name="id" value="1"/>
        <property name="name" value="彭于晏"/>
    </bean>
    <!--
    -->
    <bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
        <property name="targetBeanName" value="user"/>
    </bean>
    <bean id="superUser" class="ioc.SuperUser" parent="user"
          primary="true">
        <property name="address" value="杭州"/>
    </bean>
</beans>

classpath:/META-INF/dependency-lookup.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">

    <import resource="dependency-lookup.xml"/>
  <!--  <bean id="useRepositoryr" class="ioc.injection.repositpry.UserRepository">
        &lt;!&ndash; 手动配置 硬编码 &ndash;&gt;
        <property name="users">
            <list>
                <ref bean="superUser"/>
                <ref bean="user"/>
            </list>
        </property>
    </bean>-->

    <bean id="useRepository" class="ioc.injection.repositpry.UserRepository" autowire="byType">
    </bean>
</beans>

返回发现定义bean个数,使用BeanFactory的情况

// 有多个bean对象的情况
public static void lookUpByTypeComplex() {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
    int  theNumberOfBeanDefinitionsFound = reader.loadBeanDefinitions("classpath:/META-INF/dependency-lookup.xml");
    System.out.println("Bean 定义加载的数量");
    if(beanFactory  instanceof ListableBeanFactory){
        ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory;
        Map<String, User> beansOfType = listableBeanFactory.getBeansOfType(User.class);
        System.out.println("集合类型:" + beansOfType);
    }
}

2.2 ApplicationContext容器注解方式

package ioc;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

/**
 * 注解能力 {@link ApplicationContext} 作为 IoC 容器示例
 * @since
 */
@Configuration
public class AnnotationApplicationContextAsIoCContainerDemo {

    public static void main(String[] args) {
        // 创建 BeanFactory 容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 将当前类 AnnotationApplicationContextAsIoCContainerDemo 作为配置类(Configuration Class)
        applicationContext.register(AnnotationApplicationContextAsIoCContainerDemo.class);
        // 启动应用上下文
        applicationContext.refresh();
        // 依赖查找集合对象
        lookupCollectionByType(applicationContext);
        // 关闭应用上下文
        applicationContext.close();
    }

    /**
     * 通过 Java 注解的方式,定义了一个 Bean
     */
    @Bean
    public User user() {
        User user = new User();
        user.setId(1L);
        user.setName("小马哥");
        return user;
    }

    private static void lookupCollectionByType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map<String, User> users = listableBeanFactory.getBeansOfType(User.class);
            System.out.println("查找到的所有的 User 集合对象:" + users);
        }
    }

}

3. Spring IoC容器的生命周期

启动 applicationContext.refresh();

具体详情可以参考 # Spring IOC源码分析-Bean的生命周期