这是我参与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();
}
}