Java 在春天,豆子内部是如何被破坏的?

Java 在春天,豆子内部是如何被破坏的?,java,spring,inversion-of-control,Java,Spring,Inversion Of Control,当一个bean被声明为内部bean时,它应该和外部bean一起被销毁。但在下面的例子中,这种情况不会发生,因为没有调用bean的destroy方法 innerbeans-spring.xml <bean id="car" name="carBean" class="com.semanticbits.shoaib.innerbeans.Car" destroy-method="destroy" init-method="init"> <property name="eng

当一个bean被声明为内部bean时,它应该和外部bean一起被销毁。但在下面的例子中,这种情况不会发生,因为没有调用bean的destroy方法

innerbeans-spring.xml

<bean id="car" name="carBean" class="com.semanticbits.shoaib.innerbeans.Car" destroy-method="destroy" init-method="init">
    <property name="engine">
        <bean class="com.semanticbits.shoaib.innerbeans.Engine" destroy-method="destroy" init-method="init">

        </bean>
    </property>
</bean>
Engine.java:只需在此处编写所需代码

 public void init(){
    System.out.println("Car init method");
 }
 public void destroy(){
    System.out.println("Car destroy method");
 }


  public static void main(String[] args){
    ConfigurableApplicationContext context=(ConfigurableApplicationContext)ApplicationContextFactory.getApplicationContext("innerbeans-spring.xml");
    Car car=context.getBean("car",Car.class);
    context.getBeanFactory().destroyBean("car",car);
}
public void init(){
    System.out.println("Engine init method");
}

public void destroy(){
    System.out.println("Engine destroy method");
}
输出:

Engine init method
Car init method
Car destroy method
public static void main(String[] args){
   ConfigurableApplicationContext context=(ConfigurableApplicationContext)ApplicationContextFactory.getApplicationContext("innerbeans-spring.xml");
   Car car=context.getBean("car",Car.class);
   context.getBeanFactory().destroyBean("car",car);
   //now here Car bean is destroy.
   //when I call then check the output section.

   context.getBeanFactory().destroySingletons();


}
Engine init method
Car init method
Car destroy method
Car destroy method
Engine destroyed.
public void destroy(){
    engine.destroy();
    System.out.println("Car destroy method");
}
我的问题是:

1)
getBeanFactory().destroyBean(字符串beanName,对象beanReference)
beanName在这里是什么意思

2) 为什么不调用引擎类的
destroy
方法,因为引擎是汽车类的内部bean

扩展问题:

Engine init method
Car init method
Car destroy method
public static void main(String[] args){
   ConfigurableApplicationContext context=(ConfigurableApplicationContext)ApplicationContextFactory.getApplicationContext("innerbeans-spring.xml");
   Car car=context.getBean("car",Car.class);
   context.getBeanFactory().destroyBean("car",car);
   //now here Car bean is destroy.
   //when I call then check the output section.

   context.getBeanFactory().destroySingletons();


}
Engine init method
Car init method
Car destroy method
Car destroy method
Engine destroyed.
public void destroy(){
    engine.destroy();
    System.out.println("Car destroy method");
}
扩展输出:

Engine init method
Car init method
Car destroy method
public static void main(String[] args){
   ConfigurableApplicationContext context=(ConfigurableApplicationContext)ApplicationContextFactory.getApplicationContext("innerbeans-spring.xml");
   Car car=context.getBean("car",Car.class);
   context.getBeanFactory().destroyBean("car",car);
   //now here Car bean is destroy.
   //when I call then check the output section.

   context.getBeanFactory().destroySingletons();


}
Engine init method
Car init method
Car destroy method
Car destroy method
Engine destroyed.
public void destroy(){
    engine.destroy();
    System.out.println("Car destroy method");
}
3) 当Car实例已经被销毁时,为什么Car的destroy()方法再次调用


提前谢谢。

如果我没有弄错的话,我相信只有当Bean工厂关闭时,发动机才会被摧毁

您也可以通过调用引擎的销毁方法,直接让汽车处理此问题:

Car.java:

Engine init method
Car init method
Car destroy method
public static void main(String[] args){
   ConfigurableApplicationContext context=(ConfigurableApplicationContext)ApplicationContextFactory.getApplicationContext("innerbeans-spring.xml");
   Car car=context.getBean("car",Car.class);
   context.getBeanFactory().destroyBean("car",car);
   //now here Car bean is destroy.
   //when I call then check the output section.

   context.getBeanFactory().destroySingletons();


}
Engine init method
Car init method
Car destroy method
Car destroy method
Engine destroyed.
public void destroy(){
    engine.destroy();
    System.out.println("Car destroy method");
}

对于
引擎

<bean class="com.semanticbits.shoaib.innerbeans.Engine" destroy-method="destroy" init-method="init">
</bean>

这意味着Spring引用了这个bean定义和它创建的实例(注入的实例)。当您决定关闭/关闭
ApplicationContext
时,Spring会遍历每个bean,如果需要,会调用它们的
destroy方法


然而,您只是在破坏
汽车
bean。
引擎
bean的生命周期与
汽车
bean无关。
engine
bean是
ApplicationContext
的一部分,即使它是在另一个
bean
定义中定义的。

请告诉我是否需要额外的代码。因为没有对
engine
bean的引用,这难道不意味着
engine
bean被破坏了吗?垃圾将收集任何内部类,
Car
bean的变量。但是为什么不调用引擎类的destroy()方法为什么显式调用引擎。destroy()…如果外部bean是垃圾收集的,那么内部bean应该自动被垃圾收集。我正在销毁car引用,它间接地应该销毁引擎,因此调用销毁回调方法。因为垃圾收集不会调用您的销毁方法。。。destroy方法通常包含您希望看到执行的“清理代码”;在我写了上面所有的代码之后,应该输出什么。除了上面的输出,它还提供了汽车销毁方法引擎销毁方法…如果汽车已经销毁,为什么还要再次销毁汽车?请查看我更新的代码。一旦carbean被销毁了,那么为什么还要调用destroy方法呢?@shoaib
destroy bean
方法用于上下文不再引用的原型bean。尝试调用
销毁Singleton
两次。在第一次调用之后,上下文将删除对它所拥有的bean的所有引用。@ShoaibChikate否,
Car
的bean定义使它成为一个singletong。但是,
destroyBean
方法并没有从
ApplicationContext
中删除对该实例的引用,特别是因为该方法要与原型bean一起使用,
ApplicationContext
没有任何引用。该方法只是用来调用
destroy方法