深入Spring专题(20)

154 阅读2分钟

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

解析依赖项

有一个名为john的Singer类型的bean,它通过使用ctx.getBean()获得另一个名为gxin的Guitar类型的bean实例,然后调用john.sing()方法时使用该实例。在该方法中,通过调用ctx.getBean("gxin")来获得Guitar类型的实例。而不是请求Spring主人椅依赖项,在这种情况下,Spring并不知道john依赖于gxin,因此有关bean的依赖项的附加信息,需要完成如下配置:

<beans ...>
	<bean id="john" class="com.ozx.Singer" depends-on="gxin"></bean>
    <bean id="gxin" class="com.ozx.Guitar"></bean>
</beans>

在该配置中,声明john bean依赖于gxin bean,用于Spring实例化bean时应考虑这一点,并确保在john之前创建gxin,john需要访问ApplicationContext,告诉Spring注入该引用,当调用john.sing()方法时,可使用该引用来获取gxin bean,而该应用是通过让Singer bean实现ApplicationContextAware接口来完成的。ApplicationContextAware接口是一个特定于Spring的接口,它为ApplicationContext对象强制实现一个setter。SpringIoC容器会自动进行检测,并且注入bean段创建时所在ApplicationContext。这一切都是在调用bean的构造函数之后完成的,因此在构造函数中使用ApplicationContext将导致NullPointerException异常。

public class Singer implements ApplicationCOntextAware{
    private ApplicationContext ctx;
    private Guitar guitar;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
	this.ctx=applicationContext;        
    }
    
    public Singer(){}
	
    public void sing(){
        guitar=ctx.getBean("gxin",Guitar.class);
        guitar.sing();
    }
}

Gxin类只有sing方法,如下所示:

public class Guitar{
    public void sing(){
        System.out.println("singing");
    }
}

运行以下代码

public class DependsOn{
    public static void main(String... args){
      GenericXmlApplicationContext ctx =  new GenericXmlApplicationContext();
        ctx.load("classpath:spring/app-context.xml");
        ctx.refresh();
        
        Singer star=ctx.getBean("star",Singer.class);
        star.sing();
    }
}

还可以直接使用一种原型注解将Singer和Guitar声明为bean,重点是使用@DependsOn注解,它被应用于在Singer类中,该注解等同于XML配置中的depends-on属性。

@Component("john")
@DependsOn("gxin")
public class Singer implements ApplicationCOntextAware{
    private ApplicationContext ctx;
    private Guitar guitar;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
	this.ctx=applicationContext;        
    }
    
    public Singer(){}
	
    public void sing(){
        guitar=ctx.getBean("gxin",Guitar.class);
        guitar.sing();
    }
}