1. 程式人生 > 實用技巧 >Spring IoC 容器概述

Spring IoC 容器概述

Spring IoC 容器概述

IoC 容器示例

/**
 * ApplicationContext 作為 IoC 容器示例
 */
public class AnnotationApplicationContextAsIoCContainerDemo {
    public static void main(String...args){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AnnotationApplicationContextAsIoCContainerDemo.class);
        applicationContext.refresh();
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
        applicationContext.close();
    }

    @Bean
    public User user(){
        User user = new User();
        user.setName("fly");
        user.setAge(12);
        return user;
    }
}
/**
 * BeanFactory 作為 IoC 容器示例
 */
public class BeanFactoryAsIoCContainerDemo {
    public static void main(String...args){
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        String location = "classpath:/META-INF/dependency-lookup-context.xml";
        reader.loadBeanDefinitions(location);
        Person person = beanFactory.getBean("person", Person.class);
        System.out.println(person);
        //Person(id=1, name=fly, city=HANGZHOU, workCities=[BEIJING, HANGZHOU], lifeCities=[BEIJING, SHANGHAI],
        // company=Company(name=beijing), context={p2=2, p1=1}, contextAsText=null)
    }
}
META-INF/dependency-lookup-context.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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    <bean id="person" class="com.fly.demo.Person">
        <property name="id" value="1"/>
        <property name="name" value="fly"/>
        <property name="city" value="HANGZHOU"/>
        <property name="workCities" value="BEIJING,HANGZHOU"/>
        <property name="lifeCities">
            <list>
                <value>BEIJING</value>
                <value>SHANGHAI</value>
            </list>
        </property>
        <property name="context">
            <props>
                <prop key="p1">1</prop>
                <prop key="p2">2</prop>
            </props>
        </property>
        <property name="company" ref="company"/>
    </bean>
    <bean id="company" class="com.fly.demo.Company">
        <property name="name" value="beijing"/>
    </bean>
</beans>
User
@Data
public class User {
    private String name;
    private Integer age;
}
Person
import lombok.Data;

import java.util.List;
import java.util.Properties;

@Data
public class Person {
    private Long id;

    private String name;

    private City city;

    private City[] workCities;

    private List<City> lifeCities;

    private Company company;

    private Properties context;

    private String contextAsText;
}
City
public enum City {
    BEIJING,
    HANGZHOU,
    SHANGHAI
}
Company
@Data
public class Company {
    private String name;
}

Spring IoC 依賴查詢

dependency-lookup-context.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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    <bean id="person" class="com.fly.demo.Person">
        <property name="id" value="1"/>
        <property name="name" value="fly"/>
        <property name="city" value="HANGZHOU"/>
        <property name="workCities" value="BEIJING,HANGZHOU"/>
        <property name="lifeCities">
            <list>
                <value>BEIJING</value>
                <value>SHANGHAI</value>
            </list>
        </property>
        <property name="context">
            <props>
                <prop key="p1">1</prop>
                <prop key="p2">2</prop>
            </props>
        </property>
        <property name="company" ref="company"/>
    </bean>
    <bean id="company" class="com.fly.demo.Company">
        <property name="name" value="beijing"/>
    </bean>


    <bean id="user" class="com.fly.demo.User">
        <property name="name" value="fly"/>
        <property name="age" value="14"/>
    </bean>
    <!-- 普通 beanDefinition GenericBeanDefinition -->
    <!-- 合併後 GenericBeanDefinition 變成 RootBeanDefinition,並且覆蓋 parent 相關配置-->
    <!-- primary = true , 增加了一個 action 屬性 -->
    <bean id="superUser" class="com.fly.demo.SuperUser" parent="user" primary="true">
        <property name="action" value="sky"/>
    </bean>

    <bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
        <property name="targetBeanName" value="user"/>
    </bean>
</beans>
Super
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Super {
}
import com.fly.demo.Super;
import com.fly.demo.User;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Map;

/**
 * 依賴查詢示例
 */
public class DependencyLookupDemo {
    public static void main(String...args){
        String location = "classpath:/META-INF/dependency-lookup-context.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(location);
        // 按照型別查詢
        lookupByType(applicationContext);
        // 按照型別查詢結合物件
        lookupCollectionByType(applicationContext);
        // 通過註解查詢物件
        lookupByAnnotationType(applicationContext);
        // Bean 延遲依賴查詢介面 ObjectFactory<T>
        lookupInLazy(applicationContext);
    }

    private static void lookupInLazy(ApplicationContext applicationContext) {
        ObjectFactory<User> objectFactory = (ObjectFactory<User>) applicationContext.getBean("objectFactory");
        System.out.println("延遲查詢:" + objectFactory.getObject());
    }

    private static void lookupByAnnotationType(ApplicationContext applicationContext) {
        Map<String, Object> objectMap = applicationContext.getBeansWithAnnotation(Super.class);
        System.out.println("查詢標註 @Super 所有的集合物件:" + objectMap);
    }

    private static void lookupCollectionByType(ApplicationContext applicationContext) {
        Map<String, User> userMap = applicationContext.getBeansOfType(User.class);
        System.out.println("查詢到的所有的 User 集合物件:" + userMap);
    }

    private static void lookupByType(ApplicationContext applicationContext) {
        // 根據型別,所以不能有重複的,或指定一個primary
        User user = applicationContext.getBean(User.class);
        System.out.println("實時查詢:" + user);
    }
}

Spring IoC 依賴注入及依賴來源

META-INF/dependency-injection-context.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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 通過匯入複用 dependency-lookup-context.xml -->
    <import resource="dependency-lookup-context.xml"/>

    <bean id="userRepository" class="com.fly.demo.UserRepository"
          autowire="byType"> <!-- Auto-Wiring -->
        <!-- 手動配置 -->
<!--        <property name="users">-->
<!--            <util:list>-->
<!--                <ref bean="superUser" />-->
<!--                <ref bean="user" />-->
<!--            </util:list>-->
<!--        </property>-->
    </bean>
</beans>
import com.fly.demo.UserRepository;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.Environment;

/**
 * 依賴注入示例
 */
public class DependencyInjectionDemo {
    public static void main(String... args) {
        String location = "classpath:/META-INF/dependency-injection-context.xml";
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(location);

        UserRepository userRepository = applicationContext.getBean("userRepository", UserRepository.class);
        // 依賴來源一:自定義 Bean
//        System.out.println(userRepository.getUsers());

        // 依賴來源二:依賴注入(內建依賴)
        System.out.println(userRepository.getBeanFactory());
        System.out.println(userRepository.getBeanFactory() == applicationContext);
        System.out.println(userRepository.getBeanFactory() == applicationContext.getBeanFactory());

        // No qualifying bean of type 'org.springframework.beans.factory.BeanFactory' available
//        System.out.println(applicationContext.getBean(BeanFactory.class));

        // 依賴來源三:容器內建 Bean
        Environment environment = applicationContext.getBean(Environment.class);
        System.out.println("獲取 Environment 型別的 Bean:" + environment);
    }
}