欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring学习--懒加载(延迟初始化Bean)与自动装配

程序员文章站 2022-05-21 19:18:24
...
**延迟初始化Bean:**   
    也叫惰性初始化,指的是不提前初始化Bean,而是只有在真正使用的时候才创建以   及初始化Bean。
    配置方式很简单,只需要在<bean>标签上指定"lazy-init"属性值为true即可延迟初始  化Bean。
    Spring容器会在创建容器时提前初始化Singleton作用域的bean,Singleton就是单例 的意思,即整个容器每个bean只有一个实例。Spring容器预先初始化Bean同城能够帮助我们提前发现配置错误,所以没有什么情况建议开启,除非有某个bean可能需要加载很大资源,而且很有可能在整个应用程序生命周期中很有可能使用不到,可以设置为延迟初始化。
    延迟初始化的Bean通常会再第一次使用的时候被初始化,或者在被非延迟初始化Bean作为以来对象注入时为依赖对象注入时在会随着初始化该Bean时初始化,因为在这个时候使用延迟初始化Bean。
        <bean id="user" 
            Class="org.liang.entity.User"  
            lazy-init="true" />

depends-on : 是指指定Bean初始化以及销毁时的顺序,使用depends-on属性指定的Bean要初始化完毕以后才会初始化当前的Bean,由于只有“Singleton”Bean能够被Spring管理销毁,所以当指定的Bean都是Singleton时,使用depends-on时,使用depends-on属性指定的Bean要在指定的Bean之后销毁。

ResourceBean.java

package org.liang.entity;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by rcc on 2018/1/29.
 */
public class ResourceBean {
    private FileOutputStream fos;
    private String fileAddress;

    //初始化方法
    public void init(){
        System.out.println("ResourceBean: ================初始化");
        System.out.println("ResourceBean: ============加载");
        try {
            this.fos = new FileOutputStream(new File(fileAddress));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


    //销毁资源方法
    public void destroy(){
        System.out.println("ResourceBean:===============销毁");
        System.out.println("ResourceBean:===============释放资源,执行一些操作");
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public FileOutputStream getFos() {
        return fos;
    }

    public void setFos(FileOutputStream fos) {
        this.fos = fos;
    }

    public String getFileAddress() {
        return fileAddress;
    }

    public void setFileAddress(String fileAddress) {
        this.fileAddress = fileAddress;
    }
}

DependentBean.java

“`
package org.liang.factory;

import org.liang.entity.ResourceBean;

import java.io.IOException;

/**
* Created by rcc on 2018/1/29.
*/
public class DependentBean {
private ResourceBean resourceBean;

//写入内容
public void write(String ss) throws IOException {
    System.out.println("DependentBean:==============写资源");
    resourceBean.getFos().write(ss.getBytes());
}

//初始化方法
public void init() throws IOException {
    System.out.println("DependentBean:==============初始化");
    resourceBean.getFos().write("DependentBean:================初始化=======".getBytes());
}
//销毁方法
public void destory() throws IOException {
    System.out.println("DependentBean:==============销毁");
    //在销毁之前需要向文本中写入销毁内容
    resourceBean.getFos().write("DependentBean:==============销毁======".getBytes());
}


public ResourceBean getResourceBean() {
    return resourceBean;
}

public void setResourceBean(ResourceBean resourceBean) {
    this.resourceBean = resourceBean;
}

}

“`Spring-config.xml

 <!--测试 懒加载-->
    <bean id="resourceBean"
          class="org.liang.entity.ResourceBean"
          init-method="init" destroy-method="destroy">
        <property name="fileAddress" value="E:/lazy.txt" />
    </bean>
    <!--
        init-method="init" :指定初始化方法,在构造器注入和setter注入完毕后执行。
        destroy-method="destroy":指定销毁方法,只有“singleton”作用域能销毁,“prototype”作用域的一定不能,
                                    其他作用域不一定能;
    -->
    <bean id="dependentBean"
          class="org.liang.factory.DependentBean"
          init-method="init"
          destroy-method="destory"
          depends-on="resourceBean"
          autowire="byName"> <!--autowire="default"-->
        <property name="resourceBean" ref="resourceBean"/>

    </bean>
    <!--在此配置中,resourceBean初始化在dependentBean之前被初始化,
           resourceBean销毁会在dependentBean销毁之后执行-->


    <!--
        自动装配:
            default:表示使用默认的自动装配,默认的是自动装配需要在<beans>标签中使用default-autowire属性指定,其支持“no”、“byName ”、“byType”、“constructor”四种自动装配
            no:意思是不支持自动装配,必须明确指定依赖。
            byName:通过设置Bean定义属性autowire="byName",意思是根据名字进行自动装配,只能用于setter注入。
     -->

MoreDependencyInjectTest .java

package org.liang.test;

import org.liang.factory.DependentBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * Created by rcc on 2018/1/30.
 */
public class MoreDependencyInjectTest {
    public static void main(String [] args){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        DependentBean dependentBean = context.getBean(DependentBean.class);
        //注册销毁回调否则销毁的方法不会执行
        context.registerShutdownHook();
        try {
            dependentBean.write("hello world!!");
        } catch (IOException e) {
            e.printStackTrace();
        }



        /*

        返回的结果:

            ResourceBean: ================初始化
            ResourceBean: ============加载
            DependentBean:==============初始化
            DependentBean:==============写资源
            DependentBean:==============销毁
            ResourceBean:===============销毁
            ResourceBean:===============释放资源,执行一些操作
          */
    }
}

自动装配

    指的是由Spring来自主地注入依赖对象,无需人工参与。

    目前Spring3.0支持“no”、“byName ”、“byType”、“constructor”四种自动装配,默认是“no”指不支持自动装配的,其中Spring3.0已不推荐使用之前版本的“autodetect”自动装配,推荐使用Java 5+支持的(@Autowired)注解方式代替;如果想支持“autodetect”自动装配,请将schema改为“spring-beans-2.5.xsd”或去掉。



           自动装配的好处是减少构造器注入和setter注入配置,减少配置文件的长度。自动装配通过配置<bean>标签的“autowire”属性来改变自动装配方式。接下来让我们挨着看下配置的含义。

           一、default:表示使用默认的自动装配,默认的自动装配需要在<beans>标签中使用default-autowire属性指定,其支持“no”、“byName ”、“byType”、“constructor”四种自动装配,如果需要覆盖默认自动装配,请继续往下看;

           二、no:意思是不支持自动装配,必须明确指定依赖。

           三、byName:通过设置Bean定义属性autowire="byName",意思是根据名字进行自动装配,只能用于setter注入。比如我们有方法“setHelloApi”,则“byName”方式Spring容器将查找名字为helloApi的Bean并注入,如果找不到指定的Bean,将什么也不注入。

        四、“byType”:通过设置Bean定义属性autowire="byType",意思是指根据类型注入,用于setter注入,比如如果指定自动装配方式为“byType”,而“setHelloApi”方法需要注入HelloApi类型数据,则Spring容器将查找HelloApi类型数据,如果找到一个则注入该Bean,如果找不到将什么也不注入,如果找到多个Bean将优先注入<bean>标签“primary”属性为true的Bean,否则抛出异常来表明有个多个Bean发现但不知道使用哪个
  五、“constructor”:通过设置Bean定义属性autowire="constructor",功能和“byType”功能一样,根据类型注入构造器参数,只是用于构造器注入方式,