Spring and Abstract class - injecting properties in abstract classes

前端 未结 3 1608
忘掉有多难
忘掉有多难 2020-12-10 11:57

I have an abstract base class with a property called \"mailserver\" which I wish to inject from the spring ioc container. However when I run the concreted implementations of

相关标签:
3条回答
  • 2020-12-10 12:35

    In my case, inside a Spring4 Application, i had to use a classic Abstract Factory Pattern(for which i took the idea from - http://java-design-patterns.com/patterns/abstract-factory/) to create instances each and every time there was a operation to be done.So my code was to be designed like:

    public abstract class EO {
        @Autowired
        protected SmsNotificationService smsNotificationService;
        @Autowired
        protected SendEmailService sendEmailService;
        ...
        protected abstract void executeOperation(GenericMessage gMessage);
    }
    
    public final class OperationsExecutor {
        public enum OperationsType {
            ENROLL, CAMPAIGN
        }
    
        private OperationsExecutor() {
        }
    
        public static Object delegateOperation(OperationsType type, Object obj) 
        {
            switch(type) {
                case ENROLL:
                    if (obj == null) {
                        return new EnrollOperation();
                    }
                    return EnrollOperation.validateRequestParams(obj);
                case CAMPAIGN:
                    if (obj == null) {
                        return new CampaignOperation();
                    }
                    return CampaignOperation.validateRequestParams(obj);
                default:
                    throw new IllegalArgumentException("OperationsType not supported.");
            }
        }
    }
    
    @Configurable(dependencyCheck = true)
    public class CampaignOperation extends EO {
        @Override
        public void executeOperation(GenericMessage genericMessage) {
            LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
        }
    }
    

    Initially to inject the dependencies in the abstract class I tried all stereotype annotations like @Component, @Service etc but even though Spring context file had ComponentScanning for the entire package, but somehow while creating instances of Subclasses like CampaignOperation, the Super Abstract class EO was having null for its properties as spring was unable to recognize and inject its dependencies.After much trial and error I used this **@Configurable(dependencyCheck = true)** annotation and finally Spring was able to inject the dependencies and I was able to use the properties in the subclass without cluttering them with too many properties.

    <context:annotation-config />
    <context:component-scan base-package="com.xyz" />
    

    I also tried these other references to find a solution:

    1. http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
    2. http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
    3. https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
    4. http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
    5. https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
    6. Using abstract factory with Spring framework
    7. Spring Autowiring not working for Abstract classes
    8. Inject spring dependency in abstract super class
    9. Spring autowire dependency defined in an abstract class
      1. Spring can you autowire inside an abstract class?

    Please try using **@Configurable(dependencyCheck = true)** and update this post, I might try helping you if you face any problems.

    0 讨论(0)
  • 2020-12-10 12:41

    Mark the abstract base class definition as abstract by using the abstract attribute , and in the concrete class definition , make the parent attribute be the name of the abstract class 's bean name

    Something like this:

    <bean id="abstractBaseClass" abstract="true" class="pacakge1.AbstractBaseClass">
      <property name="mailserver" value="DefaultMailServer"/>
    </bean>
    
    <bean id="concreteClass1" class="pacakge1.ConcreteClass1" parent="abstractBaseClass">     
      <!--Override the value of the abstract based class if necessary-->
      <property name="mailserver" value="AnotherMailServer"/>
    </bean>
    
    0 讨论(0)
  • 2020-12-10 12:45

    Properties in superclasses, abstract or not, are injected exactly the same as any other properties in Spring. You can use setter, constructor, or field injection based on XML, annotations, or Java config. You'll find extensive use of inheritance all across Spring: the DefaultMessageListenerContainer, for example. Show how you're trying to wire the property, and someone can give you an explanation of why it's not working.

    0 讨论(0)
提交回复
热议问题