当前位置: 移动技术网 > IT编程>开发语言>Java > Spring再次学习(4)

Spring再次学习(4)

2019年08月11日  | 移动技术网IT编程  | 我要评论

时隔一年多,在掌握了spring、springboot、springcloud之后

我再次回头,重新学习spring框架

 

bean的生命周期学习:

在传统的xml配置中,可以这样自定义初始化和销毁方法:

init-method="" destroy-method=""

 

注解方式的简单使用:

@configuration
public class lifecircleconfig {
    @bean(initmethod = "init",destroymethod = "destroy")
    public car car(){
        return new car();
    }
}
public class car {
    public car(){
        system.out.println("construct car!");
    }
    public void init(){
        system.out.println("car init!");
    }
    public void destroy(){
        system.out.println("car destroy!");
    }
}
public class lifecircletest {

    private static annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext(lifecircleconfig.class);

    @test
    public void test(){
        applicationcontext.close();
    }
}

注意:要有close方法,否则不会打印car销毁方法

 

打印如下:

construct car!
car init!
car destroy!

 

这里默认的是单实例bean

如果是多实例的话,按照以上的测试代码是不会打印的,因为多实例情况下,在获取bean的情况下才会创建对象

而且在多例情况下,只会调用初始化和构造方法,不会调用销毁方法

以上测试代码只完成了初始化ioc容器,所以什么都不打印

 

实现spring中接口方式:这时候不需要在@bean中进行配置

public class car implements initializingbean, disposablebean {

    public car() {
        system.out.println("construct car!");
    }

    public void afterpropertiesset() throws exception {
        system.out.println("car init!");
    }

    public void destroy() {
        system.out.println("car destroy!");
    }

}

 

使用java原生注解:

public class car {

    public car() {
        system.out.println("construct car!");
    }

    @postconstruct
    public void init() {
        system.out.println("car init!");
    }

    @predestroy
    public void destroy() {
        system.out.println("car destroy!");
    }

}

 

使用spring中bean的后置处理器:

@component
public class mybeanpostprocessor implements beanpostprocessor {
    /**
     * 初始化前调用
     */
    public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception {
        system.out.println("postprocessbeforeinitialization " + bean + " " + beanname);
        return bean;
    }

    /**
     * 初始化后调用
     */
    public object postprocessafterinitialization(object bean, string beanname) throws beansexception {
        system.out.println("postprocessafterinitialization " + bean + " " + beanname);
        return bean;
    }
}
@configuration
@componentscan("org.dreamtech.bean")
public class lifecircleconfig {
    @bean
    public car car(){
        return new car();
    }
}

 

测试后部分打印如下:

construct car!
postprocessbeforeinitialization org.dreamtech.bean.car@2d9d4f9d car
postprocessafterinitialization org.dreamtech.bean.car@2d9d4f9d car

 

beanpostprocessor原理:

查看这一段源码:

initializebean(beanname, exposedobject, mbd)方法中:

        object wrappedbean = bean;
        if (mbd == null || !mbd.issynthetic()) {
            wrappedbean = applybeanpostprocessorsbeforeinitialization(wrappedbean, beanname);
        }

        try {
            invokeinitmethods(beanname, wrappedbean, mbd);
        }
        catch (throwable ex) {
            throw new beancreationexception(
                    (mbd != null ? mbd.getresourcedescription() : null),
                    beanname, "invocation of init method failed", ex);
        }

        if (mbd == null || !mbd.issynthetic()) {
            wrappedbean = applybeanpostprocessorsafterinitialization(wrappedbean, beanname);
        }

在invokeinitmethods初始化方法之前

调用了applybeanpostprocessorsbeforeinitialization,也就是调用了所有postprocessor的before方法

在invokeinitmethods初始化方法之后

调用了applybeanpostprocessorsafterinitialization,也就是调用了所有postprocessor的after方法

 

进入applybeanpostprocessorsbeforeinitialization方法查看源码:

遍历所有的processor,一旦返回null,就会跳出循环

    @override
    public object applybeanpostprocessorsbeforeinitialization(object existingbean, string beanname)
            throws beansexception {

        object result = existingbean;
        for (beanpostprocessor beanprocessor : getbeanpostprocessors()) {
            result = beanprocessor.postprocessbeforeinitialization(result, beanname);
            if (result == null) {
                return result;
            }
        }
        return result;
    }

 

在initializebean方法之前,调用的是populatebean方法

作用:给属性赋值

        // initialize the bean instance.
        object exposedobject = bean;
        try {
            populatebean(beanname, mbd, instancewrapper);
            if (exposedobject != null) {
                exposedobject = initializebean(beanname, exposedobject, mbd);
            }
        }

 

所以:beanpostprocessor是在bean赋值之后,初始化的过程前后执行的

 

beanpostprocessor在spring底层的使用:

获取ioc容器的接口:

public interface applicationcontextaware extends aware {
    void setapplicationcontext(applicationcontext var1) throws beansexception;
}

而它就是基于beanpostprocessor的,代码过长就不截取了

class applicationcontextawareprocessor implements beanpostprocessor

 

或者是参数校验:也使用到了beanpostprocessor

public class beanvalidationpostprocessor implements beanpostprocessor, initializingbean

部分代码如下:

    public object postprocessbeforeinitialization(object bean, string beanname) throws beansexception {
        if (!this.afterinitialization) {
            this.dovalidate(bean);
        }

        return bean;
    }

    public object postprocessafterinitialization(object bean, string beanname) throws beansexception {
        if (this.afterinitialization) {
            this.dovalidate(bean);
        }

        return bean;
    }

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网