Spring Bean中构造函数,@PreDestroy,@Autowired,@PostConstrut,@PreDestroy,afterPropertiesSet,destroy执行顺序

 

Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入发生时间以及单例多例的区别、SSH线程安全问题 - QiaoZhi - 博客园
https://www.cnblogs.com/qlqwjy/p/9417034.html

 

 

Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后

  

  首先明白,spring的IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的。在这里需要提醒一下,如果我们在class中没有显示的声明构造方法,默认会生成一个无参构造方法,但是当我们显示的声明一个有参构造方法的时候,JVM不会帮我们生成无参构造方法,所以我们声明一个带参数的构造方法也需要声明一个无参构造方法。(题外话:如果父类声明一个有参构造方法,子类需要在构造方法第一行显示的调用父类构造方法,因为子类的对象也是父类的对象,所以在创建子类对象的同时也会创建父类的对象,如果父类有默认的无参构造函数,JVM会调用无参构造函数,但是有了有参的就需要我们在子类的构造函数中调用父类的有参构造函数)

 

 1.Person类只有一个有参构造方法,报错如下:

No default constructor found; nested exception is java.lang.NoSuchMethodException: zd.dms.job.ebuy.Person.<init>()

2.大体知道有三种生命周期回调方法去参与到spring的生命周期,查阅了一下如下:(创建和销毁的执行顺序也是下面顺序)

  • 在指定方法上加上@PostConstruct 或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用。
  • 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;     
  • 通过 <bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法;  

3.测试spring的顺序与注入的顺序与单例多例的问题

1.Person.java

复制代码

package zd.dms.job.ebuy;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import zd.dms.dao.ebuy.GroupDao;

public class Person implements InitializingBean,DisposableBean{
    private String name;
    
    @Autowired
    private GroupDao groupDao;

    public Person() {
        System.out.println("---------------实例化一个Person对象----------");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }

    public void init() {
        System.out.println("------------这是xml的init方法----------....");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }

    public void destory() {
        System.out.println("---------------这是xml的destroy方法....");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }
    
    @PostConstruct
    public void init2() {
        System.out.println("------------这是@PostConstruct的init方法----------....");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }
    
    @PreDestroy
    public void destory2() {
        System.out.println("---------------这是@PreDestroy的destroy方法....");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("-----------这是DisposableBean的destroy方法....");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("-------这是InitializingBean的afterPropertiesSet方法....");
        System.out.println("---------------groupDao is -----------"+groupDao);
    }
}

复制代码

 

 -----------------------单例模式的xml配置以及结果---------------------------------------:

配置:

    <bean id="person" class="zd.dms.job.ebuy.Person" autowire="byType" destroy-method="destory" init-method="init"></bean> 

 

测试:将Person类注入到Action我们访问Action

复制代码

@Namespace("/qlqTest")
@SuppressWarnings("all")
public class TestAction extends DMSActionSupport {

    @Autowired
    private Person person;
    /**
     * 
     */
    private static final long serialVersionUID = -8934360924125349297L;

    @Autowired
    private GroupAndUserService groupAndUserService;

    private Map resultMap;

    @Action("test")
    public String testAction() {
        person.getClass();
        return "js";
    }
}

复制代码

 

当我们第一次访问该Action会创建Person对象,打印结果如下:

复制代码

- ---------------实例化一个Person对象----------
---------------groupDao is -----------null
------------这是@PostConstruct的init方法----------....
---------------groupDao is -----------zd.dms.dao.ebuy.GroupDaoImpl@435598e3
-------这是InitializingBean的afterPropertiesSet方法....
---------------groupDao is -----------zd.dms.dao.ebuy.GroupDaoImpl@435598e3
------------这是xml的init方法----------....
---------------groupDao is -----------zd.dms.dao.ebuy.GroupDaoImpl@435598e3

复制代码

 

证明对象创建的顺序:

    构造器-->自动注入-->@PostConstrut-->InitializingBean-->xml中配置init方法    

 

再次调用不会打印,证明默认是单例的  singleton,也就是无论我们访问多少次Action,Spring容器中只有一个这个Person实例对象。

 

销毁的时候的结果:

复制代码

---------------这是@PreDestroy的destroy方法....
---------------groupDao is -----------zd.dms.dao.ebuy.GroupDaoImpl@435598e3
-----------这是DisposableBean的destroy方法....
---------------groupDao is -----------zd.dms.dao.ebuy.GroupDaoImpl@435598e3
---------------这是xml的destroy方法....
---------------groupDao is -----------zd.dms.dao.ebuy.GroupDaoImpl@435598e3

复制代码

 

所以销毁顺序为:

  @PreDestroy--DisposableBean-->xml中destroy-method方法

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值