gpt4 book ai didi

java - 为什么在spring中创建了两个对象?

转载 作者:行者123 更新时间:2023-11-30 08:37:02 25 4
gpt4 key购买 nike

我越来越熟悉 Spring。奇怪的是,下面的代码调用构造函数两次,而我希望它被调用一次。有人可以帮忙吗?

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");
}


}

bean 和 main:

package com.tutorialspoint;

import java.io.FileNotFoundException;
import java.util.List;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;

public class MainApp {


public static void main(String[] args) {

ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

context.start();

// Create an object
DemoClass obj = (DemoClass) context.getBean("democlassBean");

// Dump contents
obj.dumpContents();

}
}

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

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


这里还有 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
}

}

最佳答案

看来,用原型(prototype)bean来充当ApplicationListener并不是个好主意。检查http://forum.spring.io/forum/spring-projects/container/35965-applicationlistener-interface-makes-beans-eagerly-instantiated了解详情。

你可以让它工作,但需要一些额外的步骤(在带内衬的帖子中描述)。请注意,链接的帖子有些旧(2007 年),其中涵盖的一些实现细节可能不再有效。

如果您真的关心创建的实例数量 - 创建两个类 - 一个作为原型(prototype),另一个(单例)充当 ApplicationListener 怎么样?

关于java - 为什么在spring中创建了两个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37489594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com