当前位置: 首页 > 知识库问答 >
问题:

在Bean类中使用ApplicationContextAware初始化原型范围Bean成员

蓟辰沛
2023-03-14

我正在学习Spring,我只是在玩应用程序上下文软件和豆子范围。

我将附上代码,然后描述我想做的事情。

到目前为止,我已经创建了一个

点类别:

public class Point {
private int x;
private int y;

public int getX() {
    return x;
}
public void setX(int x) {
    this.x = x;
}
public int getY() {
    return y;
}
public void setY(int y) {
    this.y = y;
}

@Override
public String toString() {
    return "x: "+this.x+",y: "+this.y;
}

}

我创建了一个三角形类,其中有3个Point类的实例:

public class Triangle implements ApplicationContextAware, BeanNameAware{

private Point pointA;
private Point pointB;
private Point pointC;
private String beanName;
private ApplicationContext context=null;

public Point getPointA() {
    return pointA;
}

public void setPointA(Point pointA) {
    this.pointA = (Point)this.context.getBean("point1");
}

public Point getPointB() {
    return pointB;
}

public void setPointB(Point pointB) {
    this.pointB = (Point)this.context.getBean("point2");
}

public Point getPointC() {
    return pointC;
}

public void setPointC(Point pointC) {
    this.pointC = (Point)this.context.getBean("point3");
}

public void draw() {
    System.out.println("BeanName is: "+this.beanName);
    System.out.println(pointA);
    System.out.println(pointB);
    System.out.println(pointC);
}

@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
    this.context = arg0;
}

@Override
public void setBeanName(String arg0) {
    this.beanName = arg0;
}
}

以下是spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 5.1.1//EN" "http://www.springframework.org/dtd/spring-beans-5.1.1.dtd">

<beans>
<bean id="triangle" class="org.java.learning.Triangle" >
    <property name="pointA" ref="point1" />
    <property name="pointB" ref="point2" />
    <property name="pointC" ref="point3" />
</bean>

<bean id="point1" class="org.java.learning.Point" scope="prototype">
    <property name="x" value="0" />
    <property name="y" value="0" />
</bean>

<bean id="point2" class="org.java.learning.Point" scope="prototype">
    <property name="x" value="20" />
    <property name="y" value="20" />
</bean>

<bean id="point3" class="org.java.learning.Point" scope="prototype">
    <property name="x" value="-20" />
    <property name="y" value="20" />
</bean>

这是主类:

public class DrawingApp {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Triangle t = (Triangle) context.getBean("triangle");

        t.draw();
    }
}

所以,你会看到三个豆子的豆范围,点1点2点3原型,但它们是豆三角形的成员,其范围默认为Spring单例.xml

因此,我的假设是,这应该不起作用,除非我能以某种方式在我的< code>Triangle类中获取< code>ApplicationContext并分别设置< code>pointA 、< code>pointB 、< code>pointC,就像我在它们的setter方法中使用< code>ApplicationContext所做的那样。

不确定这是否正确,也不确定这在实时应用程序中有多有用。

因此,如果上面的代码都有效,我应该得到三行输出,如下所示:

x: 0,y: 0
x: 20,y: 20
x: -20,y: 20

但是当我运行main方法时,我得到以下错误:

警告:上下文初始化期间遇到异常-取消刷新尝试:org . spring framework . beans . factory . beancreationexception:创建在类路径资源[spring.xml]中定义的名为“triangle”的bean时出错:设置属性值时出错;嵌套异常是org . spring framework . beans . propertybatchupdateexception;嵌套的PropertyAccessExceptions (3)为:PropertyAccessException 1:org . spring framework . beans . methodinvocationexception:属性“pointA”抛出异常;嵌套异常为Java . lang . nullpointerexception PropertyAccessException 2:org . spring framework . beans . methodinvocationexception:属性“pointB”引发异常;嵌套异常为Java . lang . nullpointerexception PropertyAccessException 3:org . spring framework . beans . methodinvocationexception:属性“pointC”引发异常;嵌套异常是线程“main”org . spring framework . beans . factory . beancreationexception中的java.lang.NullPointerException异常:创建在类路径资源[spring.xml]中定义的名为“triangle”的bean时出错:设置属性值时出错;嵌套异常是org . spring framework . beans . propertybatchupdateexception;嵌套的PropertyAccessExceptions (3)为:PropertyAccessException 1:org . spring framework . beans . methodinvocationexception:属性“pointA”抛出异常;嵌套异常为Java . lang . nullpointerexception PropertyAccessException 2:org . spring framework . beans . methodinvocationexception:属性“pointB”引发异常;嵌套异常为Java . lang . nullpointerexception PropertyAccessException 3:org . spring framework . beans . methodinvocationexception:属性“pointC”引发异常;嵌套异常是org . spring framework . beans . factory . support . abstractautowirecapablebean factory . applypropertyvalues(abstractautowirecapablebean factory . Java:1685)at org . spring framework . beans . factory . support . abstractautowirecapablebean factory . populate bean(abstractautowirecapablebean factory . Java:1400)at org . spring framework . beans . factory . support . abstractautowirecapablebean factory . docreatebean(abstractautowirecapablebean factory . Java:Java嵌套的PropertyAccessExceptions (3)为:PropertyAccessException 1:org . spring framework . beans . methodinvocationexception:属性“pointA”抛出异常;嵌套异常为Java . lang . nullpointerexception PropertyAccessException 2:org . spring framework . beans . methodinvocationexception:属性“pointB”引发异常;嵌套异常为Java . lang . nullpointerexception PropertyAccessException 3:org . spring framework . beans . methodinvocationexception:属性“pointC”引发异常;嵌套异常是org . spring framework . beans . abstractpropertyaccessor . set property values(abstractpropertyaccessor . Java:122)org . spring framework . beans . abstractpropertyaccessor . set property values(abstractpropertyaccessor . Java:77)org . spring framework . beans . factory . support . abstractautowirecablebean factory . app lyPropertyValues(abstractautowirecapablebean factory . Java:1681)...13更

我相信我在设置point A、point B和point C成员变量的值时做错了什么

请让我知道我方是否需要任何细节,以消除此错误并实现我正在尝试的目标。

共有3个答案

康弘义
2023-03-14

导致代码抛出异常的两个原因:

  • 新的ClassPathXmlApplicationContext(“spring.xml”)方法无法意识到类上下文已就绪
  • 循环依赖性。创建<code>ApplicationContext

您可以使用IOC来解决您的问题。

郝峰
2023-03-14

您正在获取 NPE,因为上下文对象在下面和类似的方法中为空

public void setPointC(Point pointC) {
    this.pointC = (Point)this.context.getBean("point3");
}

仅当所有 Bean 都已初始化并且上下文对象准备就绪时,才会在应用程序上下文中设置上下文软件 Bean。

您的代码应如下所示

public void setPointC(Point pointC) {
        this.pointC = pointC;
    }
裴凯定
2023-03-14

与你所面临的错误无关:让我们来看看你的课程设置:

你希望你的观点是原型。所以每次你通过注入请求一个新的Bean,Spring都会给你一个新的实例。

现在您将原型bean注入到三角bean中,三角bean默认为单例(这意味着它只被请求和创建一次)。因此,原型bean(Point)也被请求一次,以将它们注入到单例三角bean中。

从现在开始,你的原型bean的行为不再像原型bean,这意味着它们从你的三角形bean继承了单例范围。

但是在此设置上,你很好,但你应该记住这个陷阱:只有当从容器/上下文中请求bean时,Spring才会创建原型bean的新实例。

 类似资料:
  • 我能够测试在单个bean中自动生成一个原型bean只会创建一个原型bean。 作为一个解决方案,我读到可以为原型bean定义AOP范围的代理,或者使用Spring的查找方法注入。 这是我试过的- 测试类 我是不是漏了什么?此外,对greet()方法的调用返回null。

  • 我正在尝试使用Spring开发Rest代码。 我的MongoDAO类如下所示 但我得到的错误是.. 原因:org . spring framework . beans . factory . beancreationexception:创建在文件[C:\ Users \ user \ Desktop \ ITAU \ 77 \ ABC-iCOE-WAL \ ItauBankingTransac s

  • 我正在使用一些现有的代码,它正在做我以前没有见过的事情。我已经处理了使用方法注入将原型bean自动转换为单例,或者使用getBean()从上下文中获取bean。我在这段代码中看到的是一个bean,它是一个原型,使用getBean()检索,它具有自动连接的依赖关系。这些大部分都是单例bean,这是有道理的。但是有另一个原型bean的自动生成,从我所看到的情况来看,它似乎得到了一个新的bean。我的问

  • 问题内容: 有人可以解释一下我一直只使用“原型”的Spring bean的作用域吗,但是还有其他参数可以代替吗? 我在说什么的例子 问题答案: 从Spring规范开始,支持五种类型的bean作用域: 1.单身人士(默认*) 每个Spring IoC容器将单个bean定义的作用域限定为单个对象实例。 2.原型 将单个bean定义的作用域限定为任意数量的对象实例。 3.要求 将单个bean定义的范围限

  • 我在Weblogic 12上部署了一个WebApp JSP项目作为WAR。 我的gradle构建包括mvc和webflow: 我试图配置OAuth2以使用来自我的客户端JSP应用程序的client_credentials流。 我需要@Controller类来使用WebClient并将访问令牌传播到资源服务器。 下面是创建WebClient的我的Bean。 但是我得到以下错误在编译: 然而,当我取消