深入Spring专题(26)

90 阅读2分钟

这是我参与2022首次更文挑战的第33天,活动详情查看2022首次更文挑战

当使用静态初始化方法时,这种机制带来的好处就被否认,因为无法访问任何bean的状态来加以验证,如果bean正在使用静态状态作为节约内存的机制,同时正在使用静态初始化方法来验证状态,那应考虑将静态状态移至实例状态并使用非静态初始化方法,虽然也可以使用Spring的单例管理功能来实现相同的效果,但前一种方法可以得到一个更加容易测试的bean,并且可以在必要时使用自己的状态创建该bean的多个实例。在某些情况下,需要使用在多个bean实例间共享的静态状态,此时可使用静态初始化方法。

实现InitializingBean接口

Spring中定义的InitializingBean接口允许在bean代码中定义希望bean接收的Spring已经完成配置的通知。与使初始化方法的方式一样,通过实现InitializingBean接口可创造机会来检查bean配置以确保它是有效的,并提供任何默认值。InitializingBean接口定义了一个方法,即afterPropertiesSet(),它的作用与init()方法的作用相同,使用InitializingBean接口替换了初始化方法代码如下:

public class Singer implements InitializingBean{
    private static final String DEFAULT_NAME="ozx";
    
    private Strig name;
    private int age=Integer.MIN_VALUE;
    
    public void setName(String name){
        this.name=name;
    }
    public void setAge(int age){
        this.age=age;
    }
    public void afterPropertiesSet() throws Exception{
        System.out.println("Initializing Bean");
        if(name == null){
            System.out.println("Using default name");
            name = DEFAULT_NAME;
        } 
        if(age == Integer.MIN_VALUE){
            throw new IllegalArgumentException("必须先填充age属性的值");
        }
    }
    
    public String toString(){
        return "Name:"+name+"\n Age:"+age;
    }
    
    public static void main(String... args){
       GenericXmlApplicaiotnContext ctx= new GenericXmlApplicaiotnContext();
        ctx.load("classpath:spring/app-context.xml");
        ctx.refresh();
        
        getBean("singerOne",ctx);
        getBean("singerTwo",ctx);
        getBean("singerThree",ctx);
        ctx.close();
    }
    
    public static Singer getBean(String beanName,Application ctx){
        try{
            Singer bean=ctx.getBean(beanName);
            System.out.println(bean);
            return bean;
        }catch(BeanCreationException e){
            System.out.println("异常发生在bean配置:"+e.getMessage());
            return null;
        }
    }
}