gpt4 book ai didi

java - 当 applicationContext.getBean(beanName) 明显存在时,为什么它返回 null?

转载 作者:行者123 更新时间:2023-12-02 10:04:24 26 4
gpt4 key购买 nike

我正在研究一种实验方法,该方法将采用 bean 名称、属性名称和值表达式,并使用 Spring SPeL 为该 bean 的该属性分配该值。具有此方法的类是 ManagedResource,因此我可以从 JMX 访问它。

然后我定义了另一个简单的类,给它一个属性和一个组件注释。我还将此类 Autowiring 到 jmx bean 类中,只是为了验证该类型的 bean 是否存在。

然后我启动了 SpringBoot 服务。

然后我从 VisualVM 调用该方法。

它失败了,说它找不到具有该名称的 bean。

那么,现在提供更多详细信息。

这是第一个类:

@Component
@ManagedResource
public class JMXDemonstration {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private SomeRandomThing thing;

@Value("${jmxDemonstration.name}")
private String name;

@ManagedAttribute
public String getName() { return name; }

@ManagedAttribute
public void setName(String name) { this.name = name; }

@ManagedOperation
public String buildHelloWorldMessage() {
return "Hello, " + name + ": " + thing.getId();
}

@ManagedOperation
public void assignValueToBeanProperty(String beanName, String propertyName, String expression) {
Object bean = applicationContext.getBean(beanName);

ExpressionParser parser = new SpelExpressionParser();
SimpleEvaluationContext evalContext = SimpleEvaluationContext.forReadWriteDataBinding().build();

parser.parseExpression(propertyName).setValue(evalContext, bean, expression);
}
}

这是另一个类:

@Component
public class SomeRandomThing {
private String id;

public String getId() { return id; }

public void setId(String id) { this.id = id; }
}

当我从 VisualVM 调用该方法时,我传递“SomeRandomThing”、“id”和“xxx”。

此操作失败:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'SomeRandomThing' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:685)

我还在该方法中设置了一个断点并查看了“this”,并确认存在有效的“thing”属性(如果没有,服务将不会启动)。

那么我的默认 bean 名称算法是否错误?这似乎令人难以置信,因为我还对“JMXDemonstration”、“name”和“George”进行了测试,效果非常好。

更新:

另请注意,调用“applicationContext.getBean(SomeRandomThing.class)”返回该类的 bean 实例,并且调用“applicationContext.getBeanDefinitionNames()”返回一个不包含“SomeRandomThing”的数组,但它包含“JMX演示”。

为什么 SomeRandomThing 可以通过 Autowiring 和类型作为 Bean 使用,而不是通过它的 Bean 名称?

更新:

哦,因为 bean 名称是“someRandomThing”,而不是“SomeRandomThing”。我想我最初会期望前者,但是当我看到“JMXDemonstration”的 bean 名称是“JMXDemonstration”时,我认为它会是“SomeRandomThing”,而不是“someRandomThing”。

最佳答案

Bean 命名

@Component is a class level annotation. During the component scan, Spring Framework automatically detects classes annotated with @Component.

@Component
class CarUtility {
// ...
}

By default, the bean instances of this class have the same name as the class name with a lowercase initial. On top of that, we can specify a different name using the optional value argument of this annotation.

基于注释的配置

For stereotype annotation based bean, if the name is not explicitly specified with the value field of stereotype annotations, then the name is again generated by AnnotationBeanNameGenerator which is an implementation of the BeanNameGenerator strategy interface here

如果注释的值不指示 Bean 名称,则会根据类的短名称(首字母小写)构建适当的名称。例如:

com.xyz.FooServiceImpl -> fooServiceImpl

With component scanning in the classpath, Spring generates bean names for unnamed components, following the rules described earlier: essentially, taking the simple class name and turning its initial character to lower-case. However, in the (unusual) special case when there is more than one character and both the first and second characters are upper case, the original casing gets preserved. These are the same rules as defined by doc java.beans.Introspector.decapitalize (which Spring uses here).

关于java - 当 applicationContext.getBean(beanName) 明显存在时,为什么它返回 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55408164/

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