Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在春天创建的两个对象为什么?_Java_Spring - Fatal编程技术网

Java 在春天创建的两个对象为什么?

Java 在春天创建的两个对象为什么?,java,spring,Java,Spring,我对春天越来越熟悉了。奇怪的是,下面的代码调用了构造函数两次,而我预期它会被调用一次。有人能帮忙吗 package com.tutorialspoint; import java.util.List; import org.springframework.context.event.ContextStartedEvent; import org.springframework.context.ApplicationListener; public class DemoClass implem

我对春天越来越熟悉了。奇怪的是,下面的代码调用了构造函数两次,而我预期它会被调用一次。有人能帮忙吗

package com.tutorialspoint;

import java.util.List;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.ApplicationListener;

public class DemoClass implements ApplicationListener<ContextStartedEvent> {

    private String message;
    private int nrOfMessages;



    public DemoClass(String mes, int nr) {
        message = mes;
        nrOfMessages = nr;
        System.out.println("Demo class constructor. Parameters: " + mes + " " + nr);
    }

    // a setter method to set List
    public void setNrOfMessages(int nr) {
        this.nrOfMessages = nr;
    }


    // Message setter
    public void setMessage(String message) {
        this.message = message;
    }

    // prints and returns all the elements of the list.
    public void dumpContents() {
            System.out.println("Message: " + message + " Nr of messages: " + nrOfMessages);
        }

    public void onApplicationEvent(ContextStartedEvent event) {
          System.out.println("ContextStartedEvent Received");
       }


}
豆子

您可以看到构造函数被调用了两次,为什么


以下是initHelloWorld的代码:

package com.tutorialspoint;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;

public class InitHelloWorld implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      System.out.println("BeforeInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }

   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      System.out.println("AfterInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }

}

似乎,让原型bean充当ApplicationListener不是一个好主意。 检查 详情请参阅

您可以让它工作,但对于一些exta步骤是必需的(在后面的文章中描述)。请注意,链接帖子有点过时(2007年),其中涉及的一些实施细节可能不再有效


如果您真的关心正在创建的实例的数量,那么创建两个类如何?一个作为原型,另一个(singleton)作为ApplicationListener?

出于病态的好奇,如果您将范围更改为singleton,会发生什么?democlassBean不是由InitHelloWorld自动连接或创建到InitHelloWorld中的吗?通过调试到构造函数中最容易检查。在调试程序中,您将看到堆栈跟踪,它应该给出构造bean的提示。@Makoto构造函数调用过一次。但它的调用也早于Contextstarted事件,对吗?我认为这是因为DemoClass是ApplicationListener。第一个实例是为了listner而创建的,另一个实例是作为bean创建的。如果您从这个bean中删除ApplicationListener,会发生什么情况?您误解了IoC:Spring正在管理这个bean(因此它可以实例化它,不管它认为有多少次需要,或者它是如何配置的)。你要的是春天能给你的任何东西。
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">


   <bean id="democlassBean" class="com.tutorialspoint.DemoClass"
    scope="prototype">
      <constructor-arg value="Hello world beans."/>
      <constructor-arg value="300"/>        
   </bean>

   <bean class="com.tutorialspoint.InitHelloWorld"></bean>


</beans>
Demo class constructor. Parameters: Hello world beans. 300
BeforeInitialization : democlassBean
AfterInitialization : democlassBean
ContextStartedEvent Received 
Demo class constructor. Parameters: Hello world beans. 300    
BeforeInitialization : democlassBean
AfterInitialization : democlassBean
Message: Hello world beans. Nr of messages: 300
package com.tutorialspoint;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;

public class InitHelloWorld implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      System.out.println("BeforeInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }

   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      System.out.println("AfterInitialization : " + beanName);
      return bean;  // you can return any other object as well
   }

}