如何在春天使用@scope(" prototype)注释制作bean原型?

时间:2018-06-10 14:58:21

标签: java spring

我有这个主要课程

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

        Triangle t = (Triangle) context.getBean("triangle");
        Triangle t1 = (Triangle) context.getBean("triangle");

        t.show();

        System.out.println(t == t1);

    }
}

三角级

@Service
@Scope("prototype")
public class Triangle {
    private Point pointa;

    public Point getPointa() {
        return pointa;
    }

    public Triangle(Point pointa) {
        this.pointa = pointa;
    }

    public void show() {
        System.out.println("POINT A (" + pointa.getX() + "," + pointa.getY() + ")");

    }

    @Override
    public String toString() {
        return "Triangle [pointa=" + pointa + "]";
    }
}

AND SPRING.XML

<context:component-scan base-package="com.spring.demo" />
<mvc:annotation-driven />
<context:component-scan base-package="com.spring.demo" />
<bean id="triangle" class="com.spring.demo.Triangle" autowire="constructor">
</bean>

<bean id="pointabc" class="com.spring.demo.Point">
    <property name="x" value="0" />
    <property name="y" value="0" />
</bean>

<context:annotation-config />

我知道要制作一个bean原型,我们使用scope =&#34; prototype&#34;在spring.xml中。 但我想只使用@scope("prototype")制作bean原型。 我不知道为什么上面的代码不能正常工作。 我已经研究了很多,但找不到任何答案

System.out.println(t == t1); this gives me true while ideally it should be false.

4 个答案:

答案 0 :(得分:1)

Triangle声明为prototype无效,因为它已在spring.xml中以单身形式进行实例化。

关键是每次需要时都要求一个新的原型bean。

这可以通过使用配置类(并从<bean id="triangle" ...删除spring.xml来实现:

package com.spring.demo;

@Configuration
public class MyProvider {

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Triangle create() {
        return new Triangle();
    }

}

用法如下:

package com.spring.demo;

@Component
public class MySingleton {

    @Autowired
    private MyProvider myProvider;

    @PostConstruct // will execute this method once app context loaded    
    public void doStuffThatNeedsAPrototypeBeanInstance() {
        Triangle t1 = myProvider.create();
        Triangle t2 = myProvider.create();
        ...
    }
}

添加@PostConstruct会导致在初始化应用程序上下文后调用该方法,而不是在main方法中运行。这样,执行就在spring bean中,可以通过注释轻松访问其他spring bean。

答案 1 :(得分:0)

由于ApplicationContext有多个实现,因此ClassPathXmlApplicationContext one用于XML bean配置。

在XML方式中,您只需在bean元素中设置scope属性。

AnnotationConfigApplicationContext是用于基于Java的配置的ApplicationContext的实现,用于基于注释的配置,如@Bean等。

如果要使用注释方式,则需要定义基于Java的配置,并需要使用 AnnotationConfigApplicationContext 对象。

@Configuration
public class AppConfiguration{
   @Bean 
   @Scope("prototype")
   public Triangle triangle(){
      return new Triangle();
   }
}

然后获得如下的豆。

  ApplicationContext ctx = 
         new AnnotationConfigApplicationContext(AppConfiguration.class);

      Triangle triangle= ctx.getBean(Triangle.class);

答案 2 :(得分:0)

对于注释配置,我们使用 AnnotationConfigApplicationContext 实现抽象 应用 上下文

public class Scope{

    public static void main(String[] args) {
    AbstractApplicationContext context = new AnnotationConfigApplicationContext(TeacherConfig.class);
    Teacher tea=(Teacher) context.getBean("teacher");
    Teacher tea1=(Teacher) context.getBean("teacher");
    System.out.println(tea==tea1);
        }

}

教师课程

public class Teacher {
public void print(String msg){
    System.out.println("TEACHER -->"+msg);
}

<强> TeacherConfig

@Configuration
public class TeacherConfig {

    @Bean(name = "teacher")
    @Scope(value=ConfigurableBeanFactory.SCOPE_SINGLETON)
    public Teacher Teacher() {
        return new Teacher();
    }
}

@Configuration告诉Spring这是Spring的配置文件,相当于spring.xml,并通过@Bean定义bean。

System.out.println(tea==tea1);的输出为 TRUE

答案 3 :(得分:0)

通过扩展@AshishUpadhyay给出的答案,我对代码进行了一些更改。上面的答案是针对单例范围的。对于原型,只需进行少量更改。

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;


public class Scope{

    public static void main(String[] args) {
    AbstractApplicationContext context = new AnnotationConfigApplicationContext(TeacherConfig.class);
    Teacher tea=(Teacher) context.getBean(Teacher.class);
    Teacher tea1=(Teacher) context.getBean(Teacher.class);
    System.out.println(tea);
    System.out.println(tea1);
    System.out.println(tea==tea1);
        }

}

老师课:

public class Teacher {
    public void print(String msg) {
        System.out.println("TEACHER -->" + msg);
    }
}

TeacherConfig类:

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class TeacherConfig {

    @Bean()
    @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Teacher Teacher() {
        return new Teacher();
    }
}

运行Scope类后,输出为 false (对于原型,这是预期的)。

希望这会对某人有所帮助。