Pawan
Pawan

Reputation: 32331

How can i get access to the same instance of the class without creating one more bean id

I am new to Spring and the project which i am in currently is using Spring IOC . This is the current Setup of my Application , which i tried to represent as Standalone This below class is started as a Process during server startup

Client.java

public final class Client {
    public static void main(String[] args) {
        try {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");
            String[] beans = ctx.getBeanDefinitionNames();
            for (String string : beans) {
                System.out.println(beans);
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

context.xml





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



    <bean id="stream-core" class="com.StreamHandler" scope="singleton" init-method="init">
          <constructor-arg>
             <ref bean="streamingthread"/>
          </constructor-arg>
           </bean>

          <bean id="streamingthread" class="com.StreamingThread" scope="singleton" >
           </bean>

         </beans>

StreamHandler.java

package com;
    public class StreamHandler {
    private StreamingThread streamThread;
    public StreamHandler(StreamingThread streamThread) {
        this.streamThread = streamThread;
    }
    public void init() {
        this.streamThread.start();
    }
}

StreamingThread.java

   package com;
    import java.util.HashSet;
    import java.util.Set;
    public class StreamingThread extends Thread {
        private Set<String> streamSet = new HashSet();
        public void run() {
            while (true) {
                for (int i = 0; i < 12; i++) {
                    streamSet.add("Test" + 1);
                    System.out.println("Run Called");
                }
            }
        }
    }

Now my question is that , i have got another class by name UbscHandler in which i need access to the streamSet which is present inside StreamingThread class

So i tried this way

added one more bean id inside the context.xml file as shown

<context:annotation-config />
     <bean id="streamingthreadnew" class="com.StreamingThread" scope="singleton" > 


        @Autowired
        @Qualifier("streamingthreadnew")
        private StreamingThread sThread;

I am facing 2 issues here

  1. i am not able to access the streamSet as it is private .

2.Instead of creating one more bean id can i get access to that particular class using Spring style .

Edited Part

Right now i am getting

 Hi Streamed Thread Called0
java.lang.NullPointerException
    at com.Client.anotherMethod(Client.java:33)
    at com.Client.main(Client.java:26)

this is my context.xml

  <bean id="streamingthread" class="com.StreamingThread" scope="singleton" >
   </bean>

 </beans>



    **This is StreamingThread**     




   package com;

    import java.util.Set;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public  class Client{
        @Autowired
        @Qualifier("streamingthread")
        private StreamingThread streamingthread;
        public void run()
        {
            while(true)
            {
            }
        }
        public static void main(String[] args) {
            try {
                ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");
                String[] beans = ctx.getBeanDefinitionNames();
                for (String string : beans) {
                }
                Client c = new Client();
                c.anotherMethod();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
        public void anotherMethod()
        {
            Set set = streamingthread.getData();
            System.out.println(set.size());
        }
    }

This is my StreaminThread class

   package com;
    import java.util.HashSet;
    import java.util.Set;
    public class StreamingThread extends Thread {
        int i=0;
        StreamingThread()
        {
            System.out.println("Hi Streamed Thread Called"+i);
        }

        private  Set<String> streamSet = new HashSet();


        public Set getData()
        {
            return streamSet;
        }

        public void run() {
            /*while (true) {
                for (int i = 0; i < 12; i++) {
                    streamSet.add("Test" + 1);
                //s System.out.println("Run Called"+i);
                }
            }*/
        }
    }

Upvotes: 0

Views: 1529

Answers (1)

JB Nizet
JB Nizet

Reputation: 692073

If you want the same object to be injected, then you must not define another bean, but use the same definition:

<beans>
    <bean id="stream-core" class="com.StreamHandler" scope="singleton" init-method="init">
        <constructor-arg><ref bean="streamingthread"/></constructor-arg>
    </bean>

    <bean id="streamingthread" class="com.StreamingThread" scope="singleton" />
</beans>

And if you want a field to be accessible, then add a method to your class that lets you access the field.

EDIT:

You can only inject (autowire) Spring beans into other Spring beans, obtained from the application context. Client is not a Spring bean, and you get an instance of it using new Client(). Spring is totally unaware of this class and of its instanciation, so it can't inject any object into this Client instance.

You must get the StreamingThread from the application context:

StreamingThread streamingThread = applicationContext.getBean(StreamingThread.class);

Upvotes: 1

Related Questions