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
}
}