zoukankan      html  css  js  c++  java
  • [Spring] 一个例子了解Spring如何实例化Bean

    Spring框架的基础使用

    XML配置信息,Bean的不同实例化方式,注入

    实例化

    XML文件中的参数设置

    1、通过构造器进行实例化(重点,常用方式)

     <bean name="aClss2" class="com.stu.bean.AClass"></bean>

      id:指定bean的名称,用于在spring中查找这个bean对象,除了id属性,也可以使用name属性来作为名称

        注意:

        (1)在同一个Spring容器中不能有id,name或id和name两两相同的bean定义

        (2)id属性比name属性更严格,因此绝大多数时候使用id属性

      class:指定bean的类型,用于从spring容器中查找这个bean对象

         根据class对应的类型来从容器中获取对象
         如果在bean定义中有多个定义对应的类型都能匹配,则发生异常

        抽象类和接口不能被实例化 通过该方式实例化

    2、通过静态工厂方法进行实例化

     <bean id="cal" class="java.util.Calendar" factory-method="getInstance"></bean>

      id:指定bean的名称
      class:指定工厂类型
      factory-method:用于指定工厂中创建bean对象的工厂方法,必须用static修饰

    3、通过实例工厂方法进行实例化

      <!-- 1.创建实例工厂 -->
    <bean id="ggncal" class="java.util.GregorianCalendar"></bean>
      <!-- 2.指定实例工厂并调用其中的实例工厂方法来获取对象 -->
    <bean id="date" factory-bean="ggncal" factory-method="getTime"></bean>

    4.JavaBean的作用域 scope属性

      scope="prototype":多例的

      scope="singleton":单例的(默认)

    Bean的生命周期

    1. bean的定义 (xml文件、注解、java代码)
    2. bean的初始化
      init-method="  "  当bean在被初始化的时候,会被调用的方法

      (1)如果是singleton的bean,则在容器创建时就会初始化单例bean ,初始化方法只会被调用一次
      (2)对于prototype的bean,则在要获取该bean的对象时进行初始化, 初始化方法在每次获取对象时都会被调用

    3. bean的调用
      容器对象中的getBean()方法进行调用

    4. bean的销毁
      销毁方法是在web环境下,停止服务时调用或通过销毁容器对象时调用
      注意:对于singleton的bean,其生命周期完全有Spring容器控制,对于prototype则不完全是。

      ps:
      对于初始化方法和销毁方法吗,可以在beans节点中配置 default-init-method、default-destroy-method 来指定容器中每个bean的默认初始化方法,
      如果在单独的bean中也配置了它自己的初始化方法和销毁方法,则以bean节点中单独配置的那个为准

    5. 延迟实例化

      在ApplicationContext实现的默认行为就是在容器启动时将所有的singleton bean提前进行实例化
      如果不想让一个singleton bean在ApplicationContext初始化时就提前实例化,可以使用bean元素的lazy-init属性进行改变
      对于一个延迟实例化的bean,将在第一次调用时进行实例化

      lazy-init="true" 延迟加载


    A.通过构造器实例化和静态工厂实例化

    先构建用来测试的两个实体类 AClass.java 和 BClass.java

    AClass.Java

    import java.io.Serializable;
    
    /**
     * 文件名称: com.stu.bean.AClass.java<br/>
     * 初始作者: Administrator<br/>
     * 创建日期: 2018-2-1<br/>
     * 功能说明: 例子用到的第一个类 <br/>
     * =================================================<br/>
     * 修改记录:<br/>
     * 修改作者 日期 修改内容<br/>
     * ================================================<br/>
     * Copyright (c) 2010-2011 .All rights reserved.<br/>
     */
    public class AClass implements Serializable {
    
        private static final long    serialVersionUID    = 6558544854955394381L;
        /** 类的名称 **/
        private String                name;
        /** 类开头的字母 **/
        private String                index;
    
        public AClass() {
    
        }
    
        public AClass(String name, String index) {
    
            this.name = name;
            this.index = index;
        }
    
        public String getName() {
    
            return name;
        }
    
        public void setName(String name) {
    
            this.name = name;
        }
    
        public String getIndex() {
    
            return index;
        }
    
        public void setIndex(String index) {
    
            this.index = index;
        }
    
        public void init() {
    
            System.out.println("在AClass中定义的初始化时调用的方法init...");
        }
    
        public void destroy() {
    
            System.out.println("在AClass中定义的销毁时调用的方法destroy...");
        }
    
        @Override
        public String toString() {
    
            return "AClass [index=" + index + ", name=" + name + "]";
        }
    
    }

    BClass.java

    import java.io.Serializable;
    
    /**
     * 文件名称: com.stu.bean.BClass.java<br/>
     * 初始作者: Administrator<br/>
     * 创建日期: 2018-2-1<br/>
     * 功能说明:例子用到的第二个类 <br/>
     * =================================================<br/>
     * 修改记录:<br/>
     * 修改作者 日期 修改内容<br/>
     * ================================================<br/>
     * Copyright (c) 2010-2011 .All rights reserved.<br/>
     */
    public class BClass implements Serializable {
    
        private static final long    serialVersionUID    = 7680390121166235795L;
    
        private String                name;
        private int                    age;
        /** 引入一个AClass参数,用来测试注入操作 **/
        private AClass                aClass;
    
        public BClass() {
    
        }
    
        public BClass(String name, int age, AClass aClass) {
    
            super();
            this.name = name;
            this.age = age;
            this.aClass = aClass;
        }
    
        public AClass getaClass() {
    
            return aClass;
        }
    
        public void setaClass(AClass aClass) {
    
            this.aClass = aClass;
        }
    
        public String getName() {
    
            return name;
        }
    
        public void setName(String name) {
    
            this.name = name;
        }
    
        public int getAge() {
    
            return age;
        }
    
        public void setAge(int age) {
    
            this.age = age;
        }
    
        @Override
        public String toString() {
    
            return "BClass [aClass=" + aClass + ", age=" + age + ", name=" + name + "]";
        }
    
    }

    通过构造器进行实例化:applicationContext.xml

        <!--
            id:例子在bean中的名字,值不可重复 
            class:例子类的类型,在底层个,通过反射原理进行实例化。
            scope:作用域范围,'singleton'为单例;'prototype'不为单例; 
            init-method:初始方法名称,自定义。
            destroy-method:销毁执行的方法名称。
            lazy-init:懒加载
        -->
        <!-- 接口和静态类无法通过Spring添加 -->
        <bean id="aClass" class="com.stu.bean.AClass" scope="singleton"
            init-method="init" destroy-method="destroy" lazy-init="default"></bean>
    
        <!-- 使用name声明 -->
        <bean name="aClss2" class="com.stu.bean.AClass"></bean>
    
        <!--
            实例化静态方法 ,以Calendar为例 ,Java中初始化为:new Calendar().getInstance();
            factory-method:用于指定工厂中创建bean对象的工厂方法,必须是static修饰
        -->
        <bean id="cal" class="java.util.Calendar" factory-method="getInstance"></bean>
    
        <!-- 1.创建实例工厂 -->
        <bean id="ggncal" class="java.util.GregorianCalendar"></bean>
        <!-- 2.指定实例工厂并调用其中的实例工厂方法来获取对象 -->
        <bean id="date" factory-bean="ggncal" factory-method="getTime"></bean>

    Demo02.java

    public static void main(String[] args) {
    
            ApplicationContext ac = new ClassPathXmlApplicationContext(
            "classpath:applicationContext.xml");
            // getBean中传入xml中的id属性
            //aClass作用范围是单例的,所以内存地址是一致的
            System.out.println(ac.getBean("aClass"));
            System.out.println(ac.getBean("aClass", AClass.class));
    
            // 实例静态类
            System.out.println(ac.getBean("cal", GregorianCalendar.class));
    
            //实例工厂
            System.out.println(ac.getBean("date",Date.class));
        }

    运行结果:

    在AClass中定义的初始化时调用的方法init...
    AClass [index=null, name=null]
    AClass [index=null, name=null]
    java.util.GregorianCalendar[time=1517484929359,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2018,MONTH=1,WEEK_OF_YEAR=5,WEEK_OF_MONTH=1,DAY_OF_MONTH=1,DAY_OF_YEAR=32,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=35,SECOND=29,MILLISECOND=359,ZONE_OFFSET=28800000,DST_OFFSET=0]

    B.依赖注入(DI)

    IOC:控制反转(Inversion of control),原本由Java代码创建类的实例的权利交给了Spring容器进行创建,原本有Java代码维护的对象之间的依赖关系交给Spring容器进行维护
    IOC能够降低软件模块或组件之间的耦合度

    DI:依赖注入(Dependency Injection),DI的原理就是将一起工作的具有关系的对象,通过构造方法参数或方法参数传入,建立关系,因此,容器的工作就是创建bean时注入那些依赖关系,DI是IOC一种体现。

    (setter注入,构造器注入,自动装配)

    applicationContext.xml 中添加

        <!-- setter注入 -->
        <bean id="bClass" class="com.stu.bean.BClass">
            <!--
                property:表示JavaBean中要被注入的属性 name:属性名 value:属性值(简单类型的属性值)
                ref:属性值(关联的JavaBean类型的id)
            -->
            <property name="name" value="This is BClass"></property>
            <property name="age" value="1"></property>
        </bean>
    
        <!-- 对BClass中的AClass类型属性赋值 -->
        <bean id="a2" class="com.stu.bean.AClass">
            <property name="name" value="This is a2"></property>
            <property name="index" value="A"></property>
        </bean>
        <bean id="b2" class="com.stu.bean.BClass">
            <property name="name" value="This is b2"></property>
            <property name="age" value="1"></property>
            <!-- 使用ref传值 -->
            <property name="aClass" ref="a2"></property>
        </bean>
    
        <!-- 通过构造器注入 -->
        <!-- 通过构造函数实例化
            index:参数位置
            value:参数的值
         -->
        <bean id="b3" class="com.stu.bean.BClass">
            <constructor-arg index="0" value="This is b3"></constructor-arg>
            <constructor-arg index="1" value="1"></constructor-arg>
            <constructor-arg index="2" ref="a3"></constructor-arg>
        </bean>
        <bean id="a3" class="com.stu.bean.AClass">
            <constructor-arg index="0" value="this is a3"></constructor-arg>
            <constructor-arg index="1" value="1"></constructor-arg>
        </bean>
    
        <!-- 自动注入 -->
        <!--
            autowire="byName" : 属性名=Bean Id autowire="byType" :
            如果有多个相同类型的bean都能匹配成功吗,则出现错误
        -->
        <bean id="a4" class="com.stu.bean.AClass" autowire="byName">
            <property name="name" value="this is a4"></property>
            <property name="index" value="A"></property>
        </bean>

    Demo03.java

        public static void main(String[] args) {
    
            ApplicationContext ac = new ClassPathXmlApplicationContext(
            "classpath:applicationContext.xml");
            // 没有实现对AClass的属性赋值
            System.out.println(ac.getBean("bClass"));
    
            // 对AClass属性赋值
            System.out.println(ac.getBean("b2", BClass.class));
    
            /**
             * 使用构造注入
             */
            System.out.println(ac.getBean("b3", BClass.class));
    
            /**
             * 自动注入
             */
            System.out.println(ac.getBean("a4"));
        }

    运行结果

    在AClass中定义的初始化时调用的方法init...
    BClass [aClass=null, age=1, name=This is BClass]
    BClass [aClass=AClass [index=A, name=This is a2], age=1, name=This is b2]
    BClass [aClass=AClass [index=1, name=this is a3], age=1, name=This is b3]
    AClass [index=A, name=this is a4]
  • 相关阅读:
    实现字符串的翻转
    svn的安装和配置
    insert php code test
    收集的一些题
    制作多选框,并通过PHP获取多选框数据
    laravel 导出
    laravel migrate 指定文件执行
    laravel facebook等第三方授权登录
    Mysql 时间字段(加上或者减去一段时间)
    配置指定日志记录目录
  • 原文地址:https://www.cnblogs.com/x-you/p/8401070.html
Copyright © 2011-2022 走看看