Spring frame base (02): Bean's life cycle, scope, assembly summary

This article Source: GitHub · Click here || GitEE · Click here

First, the assembly method

Bean concepts: Spring application framework managed by the Spring container is responsible for creating, assembling, set properties, and then manage the entire life cycle of the object, called Bean object.

1, XML format assembly

Spring Bean most traditional way of management.

  • Configuration
    <bean id="userInfo" class="com.spring.mvc.entity.UserInfo">
    <property name="name" value="cicada" />
    </bean>
  • Test code
    ApplicationContext context01 = new ClassPathXmlApplicationContext("/bean-scan-02.xml");
    UserInfo userInfo = (UserInfo)context01.getBean("userInfo") ;
    System.out.println(userInfo.getName());

2, scanning notes

In the actual development: replace commonly used annotation xml configuration file.

  • Common Annotations
    @Component <==> <bean class="Class">
    @Component("id") <==> <bean id="id" class="Class">
    @Repository :Mvc架构中Dao层Bean的注解
    @Service:Mvc架构中Service层Bean的注解
    @Controller:Mvc架构中Controller层Bean的注解
  • Use Cases
// 1、注解代码块
@Component("infoService")
public class InfoServiceImpl implements InfoService {
    @Override
    public void printName(String name) {
        System.out.println("Name:"+name);
    }
}

// 2、配置代码块
@ComponentScan // 组件扫描注解
public class BeanConfig {

}
  • Test code
    @RunWith(SpringJUnit4Cla***unner.class)
    @ContextConfiguration(classes = BeanConfig.class)
    public class Test01 {
    @Autowired
    private InfoService infoService ;
    @Test
    public void test1 (){
        infoService.printName("cicada");
        System.out.println(infoService==infoService);
    }
    }

3, XML configuration scanning

ComponentScan annotations used above, can also be arranged in a uniform profile, the same effect, but also simplify the code.

<context:component-scan base-package="com.spring.mvc" />

4, Java code is assembled

This annotation-based Configuration, Management Bean creation, in the framework of SpringBoot and SpringCloud's very common.

  • Class Code Configuration
    @Configuration // 配置类注解
    public class UserConfig {
    @Bean
    public UserInfo userInfo (){
        System.out.println("userInfo...");
        return new UserInfo() ;
    }
    }
  • Test code
    @RunWith(SpringJUnit4Cla***unner.class)
    @ContextConfiguration(classes = UserConfig.class)
    public class Test03 {
    @Autowired
    private UserInfo userInfo ;
    @Autowired
    private UserInfo userInfo1 ;
    @Test
    public void test1 (){
        /*
         * userInfo...
         * true
         */
        System.out.println(userInfo==userInfo1);
    }
    }

Second, property value

The above is the assembly of several Bean common way, let's look Bean attribute value, based on the embodiment here Xml configuration.

1, base types and collections

  • Configuration code
    <!-- 配置Employee公共属性 -->
    <bean id="emp1" class="com.spring.mvc.entity.Employee">
    <property name="name" value="cicada" />
    <property name="id" value="1" />
    </bean>
    <bean id="emp2" class="com.spring.mvc.entity.Employee">
    <property name="name" value="smile" />
    <property name="id" value="2" />
    </bean>
    <!-- 配置Department属性 -->
    <bean id="department" class="com.spring.mvc.entity.Department">
    <!-- 普通属性值的注入 -->
    <property name="name" value="IT部门" />
    <!-- 给数组注入值 -->
    <property name="empName">
        <list>
            <value>empName1</value>
            <value>empName2</value>
            <value>empName3</value>
        </list>
    </property>
    <!-- 给List注入值:可以存放相同的值 -->
    <property name="empList">
        <list>
            <ref bean="emp1"/>
            <ref bean="emp2"/>
            <ref bean="emp1"/>
        </list>
    </property>
    <!-- 配置Set属性,相同的对象会被覆盖 -->
    <property name="empSet">
        <set>
            <ref bean="emp1"/>
            <ref bean="emp2"/>
            <ref bean="emp1"/>
        </set>
    </property>
    <!-- 配置Map属性,key相同的话,后面的值会覆盖前面的 -->
    <property name="empMap">
        <map>
            <entry key="1" value-ref="emp1" />
            <entry key="2" value-ref="emp2" />
            <entry key="2" value-ref="emp1" />
        </map>
    </property>
    <!-- 配置属性集合 -->
    <property name="pp">
        <props>
            <prop key="pp1">Hello</prop>
            <prop key="pp2">World</prop>
        </props>
    </property>
    </bean>
  • Test code
    public class Test05 {
    @Test
    public void test01 (){
        ApplicationContext context = new ClassPathXmlApplicationContext("/bean-value-03.xml");
        Department department = (Department) context.getBean("department");
        System.out.println(department.getName());
        System.out.println("--------------------->String数组");
        for (String str : department.getEmpName()){
            System.out.println(str);
        }
        System.out.println("--------------------->List集合");
        for (Employee smp : department.getEmpList()){
            System.out.println(smp.getId()+":"+smp.getName());
        }
        System.out.println("--------------------->Set集合");
        for (Employee emp : department.getEmpSet()){
            System.out.println(emp.getId()+":"+emp.getName());
        }
        System.out.println("--------------------->Map集合");
        for (Map.Entry<String, Employee> entry : department.getEmpMap().entrySet()){
            System.out.println(entry.getKey()+":"+entry.getValue().getName());
        }
        System.out.println("--------------------->Properties");
        Properties pp = department.getPp();
        System.out.println(pp.get("pp1"));
        System.out.println(pp.get("pp2"));
    }
    }

2, the configuration constructor

The number and type of configuration parameters, loading configuration and method of demapping the Bean.

  • Configuration code
    <!-- 这里配置2个参数,所有调用2个参数的构造函数 -->
    <bean id="employee" class="com.spring.mvc.entity.Employee">
    <constructor-arg index="0" type="java.lang.String" value="cicada"/>
    <constructor-arg index="1" type="int" value="1"/>
    </bean>
  • Test code
    public class Test06 {
    @Test
    public void test01 (){
        ApplicationContext context = new ClassPathXmlApplicationContext("/bean-value-04.xml");
        Employee employee = (Employee) context.getBean("employee");
        System.out.println(employee.getId()+":"+employee.getName());
    }
    }

3, configuration inheritance

  • Configuration code
    <!-- 配置父类信息 -->
    <bean id="student" class="com.spring.mvc.entity.Student">
    <property name="name" value="Spring" />
    <property name="age" value="22" />
    </bean>
    <!-- 配置子类信息 -->
    <bean id="grade" class="com.spring.mvc.entity.Grade">
    <!-- 覆盖 -->
    <property name="name" value="Summer" />
    <property name="degree" value="大学" />
    </bean>
  • Test code
    public class Test07 {
    @Test
    public void test01 (){
        ApplicationContext context = new ClassPathXmlApplicationContext("/bean-value-05.xml");
        Grade grade = (Grade) context.getBean("grade");
        /* Summer;0;大学  */
        System.out.println(grade.getName()+";"+grade.getAge()+";"+grade.getDegree());
    }
    }

Third, the scope

Scope: creating means for determining the number of spring bean instance, such as single embodiment Bean, prototype Bean, and the like.

Types of Explanation
singleton IOC container creates only a Bean instance, each IOC container is returned with a single embodiment Bean instance, the default configuration.
prototype IOC container can create multiple instances Bean, Bean are returned each time a new instance.
request Each HTTP request will create a new Bean, suitable for WebApplicationContext environment.
session Share a same HTTP Session Bean instance. Different HTTP Session different instance.
global-session With session scope is different, all share a Session Bean instance.

Fourth, the life cycle

In the Spring Framework Bean life cycle is very complicated, the process is as follows: instantiating, loading properties, before and after the initialization manager, destruction and the like. The following is based on a case configuration, will be more clear.

1, write BeanLife class

public class BeanLife implements BeanNameAware {
    private String name ;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        System.out.println("设置名称:"+name);
        this.name = name;
    }
    @Override
    public void setBeanName(String value) {
        System.out.println("BeanNameAware..SetName:"+value);
    }
    public void initBean() {
        System.out.println("初始化Bean..");
    }
    public void destroyBean() {
        System.out.println("销毁Bean..");
    }
    public void useBean() {
        System.out.println("使用Bean..");
    }
    @Override
    public String toString() {
        return "BeanLife [name = " + name + "]";
    }
}

2, custom loading process

BeanPostProcessor implement the interface.

public class BeanLifePostProcessor implements BeanPostProcessor {
    // 初始化之前对bean进行增强处理
    @Override
    public Object postProcessBeforeInitialization(Object obj, String beanName) throws BeansException {
        System.out.println("初始化之前..."+beanName);
        return obj ;
    }
    // 初始化之后对bean进行增强处理
    @Override
    public Object postProcessAfterInitialization(Object obj, String beanName) throws BeansException {
        System.out.println("初始化之后..."+beanName);
        // 改写Bean的名称
        if (obj instanceof BeanLife){
            BeanLife beanLife = (BeanLife)obj ;
            beanLife.setBeanName("myBeanLifeTwo");
            return beanLife ;
        }
        return obj ;
    }
}

3, the configuration file

<!-- 加载Bean的处理器 -->
<bean class="com.spring.mvc.BeanLifePostProcessor" />
<!-- 指定初始化和销毁方法 -->
<bean id="beanLife" class="com.spring.mvc.entity.BeanLife"
    init-method="initBean" destroy-method="destroyBean">
    <property name="name" value="myBeanLifeOne" />
</bean>

4, the testing process

  • Test code

    public class Test08 {
    @Test
    public void test01 (){
        ApplicationContext context = new ClassPathXmlApplicationContext("/bean-value-06.xml");
        BeanLife beanLife = (BeanLife) context.getBean("beanLife");
        System.out.println("测试结果BeanLife:"+beanLife.getName()) ;
        beanLife.useBean();
        // 关闭容器
        ((AbstractApplicationContext) context).close();
    }
    }
  • Output
    1、设置名称:myBeanLifeOne
    2、BeanNameAware..SetName:beanLife
    3、初始化之前...beanLife
    4、初始化Bean..
    5、初始化之后...beanLife
    6、BeanNameAware..SetName:myBeanLifeTwo
    7、测试结果BeanLife:myBeanLifeOne
    8、使用Bean..
    9、销毁Bean..

    Here combing Bean's life cycle, the process is very clear.

Fifth, the source code address

GitHub·地址
https://github.com/cicadasmile/spring-mvc-parent
GitEE·地址
https://gitee.com/cicadasmile/spring-mvc-parent

Spring frame base (02): Bean's life cycle, scope, assembly summary

Guess you like

Origin blog.51cto.com/14439672/2446350