为了账号安全,请及时绑定邮箱和手机立即绑定

如何创建带参数的工厂方法?

如何创建带参数的工厂方法?

哈士奇WWW 2021-08-25 17:20:16
你能帮我摆脱ApplicationContext吗?我有一个工厂,所以所有的书实例都是 spring-beans。我认为把所有的豆子都做成春豆是一个很好的决定。@Componentpublic class BookFactoryImpl implements BookFactory {    private final ApplicationContext applicationContext;    @Autowired    public BookFactoryImpl(ApplicationContext applicationContext) {        this.applicationContext = applicationContext;    }    @Override    public Book createBook(String name) {        return applicationContext.getBean(Book.class, name);    }}这是一个配置类,其@Bean方法用于实例化Book类的新实例:@Configuration@ComponentScan({"factory"})public class AppConfig {    @Bean    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)    @Lazy    public Book book(String name) {        return Book.builder().name(name).build();    }}这是我的Book实体类:@Entity@NoArgsConstructor@AllArgsConstructor@Getter@EqualsAndHashCode@ToString@Builderpublic class Book {    @Id    @GeneratedValue    private int id;    @Basic(fetch = FetchType.LAZY)    private String name;}我有更多的一个想法-注释BookFactoryImpl与@Configuration和移动@Bean在它的方法,但在这种情况下,我厂将变成@Configuration类破碎的生命周期。你怎么看,实现工厂的最佳方式是什么,以及如何减少外部依赖,比如ApplicationContext?或者把所有的工厂都做成@Configuration带有@Bean方法的类是很好的,你怎么看?
查看完整描述

2 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

不,让应用程序中的每个类都由 Spring 管理并不是一个好主意。

JPA 实体通常应该由 Spring 托管 bean 中的代码实例化


查看完整回答
反对 回复 2021-08-25
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

我通常使用以下方法:


定义将包含对工厂的依赖的单例 bean:


    public class MyService {

     private final Provider<Book> bookFactory;


     public MyService(Provider<Book> bookFactory) {

         this.bookFactory = bookFactory;

     } 

     public void doSomething() {

        Book book = bookFactory.get();

        book.setNumberOfReaders(numOfReaders); // this is a drawback, book is mutable, if we want to set runtime params (like numberOfReaders)

         ....

      }

    }

现在为 book bean 定义一个原型:


@Configuration 

public class MyConfiguration {


   @Bean

   @Scope("prototype")

   public Book book(...) {

      return new Book(...);

   }


   @Bean // scope singleton by default

   public MyService myService(Provider<Book> bookFactory) {

       return new MyService(bookFactory);

   }

}

注意,Provider 的类型是“javax.inject.Provider”,为了使用 id,导入(例如在 maven 中):


<dependency>

   <groupId>javax.inject</groupId>

   <artifactId>javax.inject</artifactId>

   <version>1</version>

</dependency>

Spring 可以处理这个,因为 4.x(我猜是 4.1)而不需要任何额外的配置


当然,这种方法消除了将应用程序上下文注入工厂的需要,并且通常需要维护工厂


一个缺点是它不允许使用参数构建对象,这些参数必须在运行时指定。


还有另一种方法,运行时生成子类并结合@Lookup注释,这里描述了它,但 IMO Provider 方法更好。


查看完整回答
反对 回复 2021-08-25
  • 2 回答
  • 0 关注
  • 168 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信