Sarronya
Sarronya

Reputation: 353

@scope - spring - setting scope "prototype" using annotations, behaves like singleton. Where am i going wrong?

When i try to use @scope("prototype") over a class, I see it behaves similar to "singleton" I am not sure where I am wrong. Any help on this is much appreciated.

Employee class - setting scope - prototype

 import org.springframework.context.annotation.Scope; 
@Scope("prototype")
public class Employee {

    private String emp_name;
    public String getEmp_name() {
        return emp_name;
    }

    public void setEmp_name(String emp_name) {
        this.emp_name = emp_name;
    }
}

Department class- setting scope - singleton

import org.springframework.context.annotation.Scope;
@Scope("singleton")
public class Department {
private String dep_name;

public String getDep_name() {
    return dep_name;
}
public void setDep_name(String dep_name) {
    this.dep_name = dep_name;
}   

}

Beans.xml

<context:component-scan base-package="com"/> 

 <!-- Scope Annotations -->
     <bean id="dep_scope" class="com.scope.annotation.Department" >
     </bean>
    <bean id="emp_scope" class="com.scope.annotation.Employee" >
     </bean>

Main App

public class MainApp {
       public static void main(String[] args) {
          ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

          Employee emp = (Employee) context.getBean("emp_scope");
          emp.setEmp_name("Saro");
          System.out.println("first"+emp.getEmp_name());

          Employee emp2 = (Employee) context.getBean("emp_scope");
          System.out.println("second"+emp2.getEmp_name());

          Department dep = (Department) context.getBean("dep_scope");
          dep.setDep_name("Maths");
          System.out.println("first"+dep.getDep_name());

          Department dep2 = (Department) context.getBean("dep_scope");
          System.out.println("second"+dep2.getDep_name());
       }
    }

Output :

firstSaro secondSaro firstMaths secondMaths

I expected secondnull instead of secondSaro

Upvotes: 2

Views: 1570

Answers (3)

You have put

context:component-scan base-package="com" 

which will try to instantiate beans if they are annotated with @Component or the other bean annotations like @Service, etc. But this does not make spring process the other annotations configuration.

if you want to process the other spring annotations you must register

context:annotation-config> .

too in order to ask spring to look for the annotations in the defined beans.

in summary

context:component-scan : will instantiate beans within the package if they are annotated with suitable annotation

context:annotation-config : will process the annotations in the configured beans irrespective of whether they are defined via annotations or xml.

Upvotes: 0

noscreenname
noscreenname

Reputation: 3370

It behaves as a singleton because this is the ways it is defined in the your xml conf. Default scope is singleton, prototype should be declares like follows

<bean id="dep_scope" class="com.scope.annotation.Department" scope="prototype">
 </bean>

If you want to use annotations, javadoc states that @Scope should be used in conjunction with @Component, like this

@Component
@Scope("prototype")
public class Employee {
    //...
}

public class ExampleUsingEmployee {    
    @Inject
    private Employee enployee; //will be automatically injected by spring    
    // ... do other stuff
}

You should avoid (if possible) using both xml and annotations.

Upvotes: 1

Nirav Chhatrola
Nirav Chhatrola

Reputation: 512

Just try to define scope in beans.xml file in bean tag.... you are using both annotation and xml ... just use either..

Or you can try to define bean using annotation ... for that you can use @Bean annotation.

@Configuration
public class Config {

   @Bean(scope=DefaultScopes.PROTOTYPE) 
   public TestBean testBean(){
      return new TestBean();
   }
}

And In your main logic you can use bellow code

TestBean testBean = ctx.getBean(TestBean.class);

Upvotes: 1

Related Questions