Spring @Autowired在一个类新实例上

Joã*_*hin 10 java spring dependency-injection autowired

我对Spring不太熟悉,我有以下情况:

存储库类:

@Repository
public class MyRepository {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

使用存储库类的类:

public class MyClass extends AbstractClass {

    @Autowired
    private MyRepository myRepository;

    //...
}
Run Code Online (Sandbox Code Playgroud)

我知道,如果我注释我MyClass@Component,并用它与一个@Autowired,那么@Autowired MyRepository解决就好了.问题是我需要创建MyClass带反射的新实例.所以MyRepository永远不会解决,并且始终为null.

有没有办法@Autowired在这种情况下使用?

更好地解释我的情况:我有一些实现AbstractClass.在我的应用程序的设置阶段,我创建了HashMap这些实现.基本上:

{"MyClass", MyClass.class}
//...
Run Code Online (Sandbox Code Playgroud)

然后我有一个Controller映射到url 的泛型/{class}?options=... 使用{class} @PathVariable,HashMap上面和反射我能够根据给定创建一个类的实例options(这部分很重要).你们认为有更好的方法吗?

提前致谢

Tho*_*sch 12

Spring本身提供了在您创建你的对象做自动装配的一些功能newnewInstance()或什么的.

要使用它,你需要一个AutowireCapableBeanFactory 你通过Spring的正常依赖注入得到的@Autowired.

@Autowired
private  AutowireCapableBeanFactory autowireCapableBeanFactory;
Run Code Online (Sandbox Code Playgroud)

然后使用其autowireBean(Object)方法将@Autowired属性注入到bean中.

Object myBean = map.get(className).newInstance();
autowireCapableBeanFactory.autowireBean(myBean);
Run Code Online (Sandbox Code Playgroud)

设计说明:

如果你真的需要上面的方法,请好好想想.AutowireCapableBeanFactory建议不要在大多数用例中使用此接口的javadoc :

BeanFactory的这个子接口并不适用于普通的应用程序代码:坚持BeanFactoryListableBeanFactory用于典型的用例.

其他框架的集成代码可以利用此接口来连接和填充Spring无法控制其生命周期的现有Bean实例.例如,这对WebWork Actions和Tapestry Page对象特别有用.


Ris*_*wal 7

您可以在这里使用工厂设计模式。

一开始这可能看起来有点复杂,但我相信在实现它之后你会喜欢它。

脚步:

  1. 在 AbstractClass 的所有实现上添加 @Component。
  2. 创建一个工厂类:

    @Component
    public class MyFactory {
    
        private final Map<String, AbstractClass> impletationMap = new HashMap<>();
    
        @Autowired
        ApplicationContext context;
    
        @PostConstruct
        public void initialize() {
            populateDataMapperMap(context.getBeansOfType(AbstractClass.class).values().iterator());
        }
    
        private void populateDataMapperMap(final Iterator<AbstractClass> classIterator) {
            while (classIterator.hasNext()) {
                AbstractClass abstractClassImpl = (AbstractClass) classIterator.next();
                impletationMap.put(abstractClassImpl.getClass().getName(), abstractClassImpl);
    
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

当这个MyFactory类的Bean被初始化时,它将查找所有AbstractClass类型的Bean并将它们放入HashMap(implementationMap)中。

现在,您可以从这个工厂获取 HashMap,然后在需要时获取实现。当您添加 AbstractClass 的新实现时,这将非常容易,因为工厂会处理它。