0

I have the following class and I am able to use which are annotated as @Component only when use ctx.getBean(). But I want to know below.

  1. Why annotation @autowired is not working.

  2. I am getting error at PathVerifier because it is interface and following factory patter. The actual implementation object will only know runtime right. So I added @Component for all implementations of my PathVerifier interface.

I have below in my context file:

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

My main classes is as follows:

@Component("verifier")
public class Verifier { 

    private static final Logger log = LoggerFactory.getLogger(Verifier.class);

    @Autowired
    private static PathVerifierFactory pathVerifierFactory;
    private static PathVerifer pathVerifier;

    public AutogenPathInfo getXMLPathData() throws Exception {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");
        FileInputParser parser = (FileInputParser) ctx.getBean("fileParser");
        pathVerifierFactory=(PathVerifierFactory) ctx.getBean("pathVerifierFactory");
        //pathVerifier=(PathVerifer) ctx.getBean("pathVerifer");
        return parser.process();
    }

    public List<Paths> splitXMLData(AutogenPathInfo pathInfo, String pathTypeId) {

        List<Paths> pathsList = new ArrayList<Paths>();
        List<Paths> pathTypes = pathInfo.getPaths();

        System.out.println("Size of 'Paths' :" + pathTypes.size());
        Iterator<Paths> pathsItr = pathTypes.iterator();

        int typeICnt = 0;

        while (pathsItr != null && pathsItr.hasNext()) {

            Paths paths = pathsItr.next();

            if (paths.getTypeid().equalsIgnoreCase(pathTypeId)) {
                pathsList.add(paths);

            }
            continue;

        }
        System.out.println("total Path types " + typeICnt);
        return pathsList;

    }

    public void verifyPathInfo() throws Exception {
        AutogenPathInfo autogenPathInfo=null;

        autogenPathInfo = getXMLPathData();

        List<String> pathIdList = getPathTypeIds(autogenPathInfo);

        if(pathIdList!=null)
        System.out.println("Size of Paths Element in XML : "+pathIdList.size());

        if(pathVerifierFactory==null){
            log.debug("pathVerifierFactory is null");           
        }

        for(String pathId: pathIdList) {
            List<Paths> pathList = splitXMLData(autogenPathInfo, pathId);
            PathVerifer pathVerifierObj = pathVerifierFactory.getPathVerifier(pathId);

            if(pathVerifierObj==null){
                log.debug("pathVerifierObj is null");           
            }

            pathVerifierObj.verifyPaths(pathList);          
        }

    } 

    private List<String> getPathTypeIds(AutogenPathInfo autogenPathInfo) {

        List<String> typeIdList=new ArrayList<String>();

        List<Paths> pathsList = autogenPathInfo.getPaths();
        Iterator<Paths> pathListIterator = pathsList.iterator();
        while(pathListIterator!=null && pathListIterator.hasNext()){

            Paths paths =  pathListIterator.next();
            if(!StringUtils.isBlank(paths.getTypeid())){
                typeIdList.add(paths.getTypeid().trim());

            }
        }
        List<String> distinctPathIdList = new ArrayList<String>(new HashSet<String>(typeIdList));
        return distinctPathIdList;

    }

}
mahesh
  • 1,523
  • 4
  • 23
  • 39

1 Answers1

3

Static fields can not autowired.

You cannot autowire or manually wire static fields in Spring. You'll have to write your own logic to do this

. Try to remove static modifier from your variables.

check this out

UPDATE

You could autowire the list of implementation objects as it follows.

<bean id="stage1" class="Stageclass"/>
<bean id="stage2" class="Stageclass"/>

<bean id="stages" class="java.util.ArrayList">
    <constructor-arg>
        <list>
            <ref bean="stage1" />
            <ref bean="stage2" />                
        </list>
    </constructor-arg>
</bean>

So inject the implementations to the factory to avoid have N @Autowired annotations

Community
  • 1
  • 1
Koitoer
  • 18,778
  • 7
  • 63
  • 86
  • Also, OP needs to use `qualifier` in order to use a specific implementation of `PathVerifier`. – RP- Feb 04 '14 at 19:20
  • thanks @Koitoer, problem 1) resolved. please help me with 2) PathVerifier is interface and has 7 implementations, so getting error " No unique bean of type [com.moodys.sfg.process.service.PathVerifer] is defined: expected single matching bean but found" – mahesh Feb 04 '14 at 19:22
  • @RP can you please let me know what is OP here in your comment? – mahesh Feb 04 '14 at 19:26
  • @Rp- please help me which qualifier and how to use it. i tried to use pathVerifier instead of "pathVerifierObj" in above code and getting below error "No unique bean of type [com.moodys.sfg.process.service.PathVerifer] is defined: expected single matching bean but found 7: [FTPVerifier, httpVerifier, localPathVerifier, RMIVerifier, sharedPathVerifier, SMTPVerifier, winServiceVerifier]" – mahesh Feb 04 '14 at 19:30
  • @mahesh OP means Original Poster (he/she who actually asked the question). You need to use `@Qualifier` annotation in combination with `@Autowired` if you want to use specific implementation of the `PathVerifier`. – RP- Feb 04 '14 at 19:31
  • @mahesh http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers – RP- Feb 04 '14 at 19:32
  • Thanks @RP, But I have 7 implemenations of PathVerifier interface. Do I need to mention all these 7 classes using @Qualifier? because I don't know which one will be called at runtime. – mahesh Feb 04 '14 at 19:35
  • @Qualified only will inject the selected one, if you think you will need some of them dynamically, use the factory and add those beans to the factory , be careful with selected scope. But at the end yes, if you have different implementation is the way – Koitoer Feb 04 '14 at 19:39
  • ya, here I am trying to get object of one of these impl classes at runtime which is of type its main interface PathVerifier, so I am autowiring interface. I am thinking how to do it. pathVerifierFactory is the factory class. – mahesh Feb 04 '14 at 19:43
  • I have similar question like below "http://stackoverflow.com/questions/12338138/how-to-implement-factory-pattern-with-spring-3-0-services" – mahesh Feb 04 '14 at 19:46
  • It seems an implementetation of strategy design pattern, but look at this post. http://stackoverflow.com/questions/4553377/how-to-efficiently-implement-a-strategy-pattern-with-spring . It seems the best way to achieve this is using dependency injection, you could use a list to save all the implementation and then inject that list in the factory. – Koitoer Feb 04 '14 at 19:50
  • I made an update in my response as an example of what I suggest. – Koitoer Feb 04 '14 at 19:53