简体   繁体   English

如何允许基本自动配置类? 当我有两个扩展它时,只有第一个被调用

[英]How allow base auto configuration class? When I have two that extend it, only the first one gets called

I have a base auto configuration class that uses generics to create the bean you want. 我有一个基本的自动配置类,该类使用泛型来创建所需的bean。 But when I test having two configs that both extend that base config class, the second one never creates its beans. 但是,当我测试有两个都扩展该基本配置类的配置时,第二个配置永远不会创建其bean。

I believe this is because the method name is the same on both, so Spring assumes that it's already created. 我相信这是因为方法名称在两者上都相同,因此Spring假定它已经创建。

Is there a way to dynamically set the name based off the generic type? 有没有一种方法可以根据通用类型动态设置名称? (or some other solution) (或其他解决方案)

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = { TestGenericBean.MyClientCreator.class, TestGenericBean.MyClientCreator2.class } )
public class TestGenericBean
{
    @Autowired
    private TestClient client;

    @Autowired
    private TestClient2 client2;

    public static class ClientConfig<T>
    {
        private Class<T> classCreator;

        public ClientConfig(Class<T> classCreator)
        {
            this.classCreator = classCreator;
        }

        /* ***** This base class's method is only called once for
         *       the first class (MyClientCreator) not for the
         *       second one (MyClientCreator2)
         */
        @Bean
        public T createClient(AsyncRestTemplate asyncRestTemplate) throws Exception
        {
            Constructor<T> constructor = classCreator.getConstructor(
                AsyncRestTemplate.class
            );

            return constructor.newInstance( asyncRestTemplate );
        }

        @Bean
        public AsyncRestTemplate asyncRestTemplate()
        {
            return new AsyncRestTemplate();
        }
    }

    @Configuration
    public static class MyClientCreator extends ClientConfig<TestClient>
    {
        public MyClientCreator()
        {
            super( TestClient.class );
        }
    }

    public static class TestClient
    {
        public AsyncRestTemplate asyncRestTemplate;

        public TestClient(AsyncRestTemplate asyncRestTemplate)
        {
            this.asyncRestTemplate = asyncRestTemplate;
        }
    }

    /* This is the second configuration class. This config's bean never gets created */
    @Configuration
    public static class MyClientCreator2 extends ClientConfig<TestClient2>
    {
        public MyClientCreator2()
        {
            super( TestClient2.class );
        }
    }

    public static class TestClient2
    {
        public AsyncRestTemplate asyncRestTemplate;

        public TestClient2(AsyncRestTemplate asyncRestTemplate)
        {
            this.asyncRestTemplate = asyncRestTemplate;
        }
    }

    @Test
    public void testBean()
    {
        System.out.print( client.asyncRestTemplate );
    }
}

You can solve your problem by inheriting the createClient method, removing the @Bean annotation on your parent class and qualifying the name in the bean title: 您可以通过继承createClient方法,删除父类上的@Bean注释并限定Bean标题中的名称来解决问题:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestGenericBean.MyClientCreator.class, TestGenericBean.MyClientCreator2.class })
public class TestGenericBean {

    // Need to remove the bean here so we don't get duplicate naming
    // @Bean
    public T createClient(AsyncRestTemplate asyncRestTemplate) throws Exception
    {
       ...
    }

    ...

    @Configuration
    public static class MyClientCreator extends ClientConfig<TestClient> {
        public MyClientCreator()
        {
            super( TestClient.class );
        }
        @Bean("testClient")
        @Override
        public TestClient createClient(AsyncRestTemplate asyncRestTemplate) throws Exception {
            return super.createClient(asyncRestTemplate);
        }
    }

    ...

    /*
     * This is the second configuration class. This config's bean never gets created
     */
    @Configuration
    public static class MyClientCreator2 extends ClientConfig<TestClient2> {
        public MyClientCreator2()
        {
            super( TestClient2.class );
        }
        @Bean("testClient2")
        @Override
        public TestClient2 createClient(AsyncRestTemplate asyncRestTemplate) throws Exception {
            return super.createClient(asyncRestTemplate);
        }
    }

    ...
}

However, ideally if you have control of the beans, you should be using the awesome Object Factory (and similar) methods for non-constructor/DI-friendly beans. 但是,理想情况下,如果您可以控制Bean,则应该对非构造函数/ DI友好的Bean使用令人敬畏的Object Factory (和类似方法)。 Cheers! 干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何扩展Fragment并使子类与ListFragment一起扩展我的基类? - How can I extend Fragment and have a subclass extend my base class along with ListFragment? 由扩展第一类的类调用时,无法使一个类中的方法完全在main方法中运行 - Unable to have the methods in one class completely run in main method when called by a class that extends first class 如何将一个类扩展到两个库? - How to extend one class to two libraries? 当前两个已经处于基-子类关系中时,如何继承第三个类中的两个类? - How to inherit two classes in a third class when the first two are in base-child class relationship already? 如何使用我的“基础”class 在 Android 中“扩展”PreferenceActivity class? - How do I “extend” PreferenceActivity class in Android with my “base” class? Java:当其他类已经扩展基类时,如何扩展基类? - Java: How to extend a base class when other classes already extend the base? 我有一个由2个对象组成的数组,当我使用for循环时,两个对象都得到了只有其中一个应该具有的更改 - I have an Array of 2 objects, when I use a for loop, both of the object gets the change that only one of them should have 扩展Thread类时如何调用run()方法 - How a run() method is called when we extend Thread class 如果我已经在数据库中有成千上万个相关实体,并且在集合中添加了新实体,那么在JPA中如何保持一对多关系 - How one to many relationship gets persisted in JPA if i have thousands of related entities already in data base and i add new entities in collection 如何添加两个不同类的ArrayList,将一个抽象类扩展为一个ArrayList? - How do I add two ArrayLists of different classes that extend an abstract class into one ArrayList?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM