如何使用Java反射创建一个@Autowired类的实例

huangapple go评论75阅读模式
英文:

How to use Java reflection to create an instance of an @Autowired class

问题

我有一个存储(作为字符串)根据用户输入的信息来使用的相关类的PostgreSQL数据库。

例如,用户输入Name,数据库中存储了值NameFinder(),代码需要创建NameFinder()的实例。

我想知道是否有一种使用反射来将此类实例化为@Autowired组件的方法,然后调用相关的函数。

我似乎找不到使用@Autowired类的指南,所以任何帮助都将不胜感激。

英文:

I have a postgres database which stores (as a String) the relevant class to use dependent on the information coming in from the user.

e.g. user has input Name, the database has the value NameFinder() stored against this and the code needs to create an instance of NameFinder().

I was wondering if there was a way of using reflection to instantiate this class as an @Autowired component, and then call the relevant function.

I can't seem to find a guide that uses @Autowired classes so any help would be appreciated.

答案1

得分: 1

为了使自动装配起作用,您需要使用@Autowired的类必须是@Component(或类似@Service的子类)。
https://www.baeldung.com/spring-autowire

为了让Spring知道要注入什么,您需要在配置中定义一个@Bean。
https://www.baeldung.com/spring-bean

至于bean中的反射实例化:

@Bean
public Name getName(Database db) {
    String nameFqn = db.getConfigTable().getNameFQN();
    return (Name) Class.forName(nameFqn).getConstructor().newInstance();
}

请注意,这里使用了一个无参数的公共构造函数。FQN代表完全限定名,即com.some.pkg.NameFinder,假设:

package com.some.pkg;

class NameFinder implements Name {
    public NameFinder(){}
}

我觉得Spring Bean也应该可以直接从FQN进行配置,而不使用反射,但我不知道如何做。尝试阅读有关BeanFactory或类似内容的资料。通常应该避免使用反射。

英文:

For autowiring to work you need the class which uses @Autowired to be a @Component (or a child like @Service ...). https://www.baeldung.com/spring-autowire

For Spring to know what to inject, you need to define a @Bean in your Configuration
https://www.baeldung.com/spring-bean

As for the reflective instantiation in the bean:

@Bean
public Name getName(Database db) {
    String nameFqn = db.getConfigTable().getNameFQN();
    return (Name) Class.forName(nameFqn).getConstructor().newInstance();
}

Note this uses a no-arg public constructor. FQN means fully-qualified name, i.e. com.some.pkg.NameFinder
assuming:

package com.some.pkg;

class NameFinder implements Name {
    public NameFinder(){}
}

I feel like a Spring Bean should be configurable also directly from a FQN without using reflection but I don't know how. Try reading up on a BeanFactory or something similar. Usually reflection is to be avoided.

huangapple
  • 本文由 发表于 2020年8月7日 18:08:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/63299616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定