猿问

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

你能帮我摆脱ApplicationContext吗?


我有一个工厂,所以所有的书实例都是 spring-beans。我认为把所有的豆子都做成春豆是一个很好的决定。


@Component

public 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

@Builder

public class Book {


    @Id

    @GeneratedValue

    private int id;


    @Basic(fetch = FetchType.LAZY)

    private String name;


}

我有更多的一个想法-注释BookFactoryImpl与@Configuration和移动@Bean在它的方法,但在这种情况下,我厂将变成@Configuration类破碎的生命周期。


你怎么看,实现工厂的最佳方式是什么,以及如何减少外部依赖,比如ApplicationContext?


或者把所有的工厂都做成@Configuration带有@Bean方法的类是很好的,你怎么看?


哈士奇WWW
浏览 169回答 2
2回答

蝴蝶刀刀

不,让应用程序中的每个类都由 Spring 管理并不是一个好主意。JPA 实体通常应该由 Spring 托管 bean 中的代码实例化

qq_花开花谢_0

我通常使用以下方法:定义将包含对工厂的依赖的单例 bean:&nbsp; &nbsp; public class MyService {&nbsp; &nbsp; &nbsp;private final Provider<Book> bookFactory;&nbsp; &nbsp; &nbsp;public MyService(Provider<Book> bookFactory) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;this.bookFactory = bookFactory;&nbsp; &nbsp; &nbsp;}&nbsp;&nbsp; &nbsp; &nbsp;public void doSomething() {&nbsp; &nbsp; &nbsp; &nbsp; Book book = bookFactory.get();&nbsp; &nbsp; &nbsp; &nbsp; book.setNumberOfReaders(numOfReaders); // this is a drawback, book is mutable, if we want to set runtime params (like numberOfReaders)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;....&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }现在为 book bean 定义一个原型:@Configuration&nbsp;public class MyConfiguration {&nbsp; &nbsp;@Bean&nbsp; &nbsp;@Scope("prototype")&nbsp; &nbsp;public Book book(...) {&nbsp; &nbsp; &nbsp; return new Book(...);&nbsp; &nbsp;}&nbsp; &nbsp;@Bean // scope singleton by default&nbsp; &nbsp;public MyService myService(Provider<Book> bookFactory) {&nbsp; &nbsp; &nbsp; &nbsp;return new MyService(bookFactory);&nbsp; &nbsp;}}注意,Provider 的类型是“javax.inject.Provider”,为了使用 id,导入(例如在 maven 中):<dependency>&nbsp; &nbsp;<groupId>javax.inject</groupId>&nbsp; &nbsp;<artifactId>javax.inject</artifactId>&nbsp; &nbsp;<version>1</version></dependency>Spring 可以处理这个,因为 4.x(我猜是 4.1)而不需要任何额外的配置当然,这种方法消除了将应用程序上下文注入工厂的需要,并且通常需要维护工厂一个缺点是它不允许使用参数构建对象,这些参数必须在运行时指定。还有另一种方法,运行时生成子类并结合@Lookup注释,这里描述了它,但 IMO Provider 方法更好。
随时随地看视频慕课网APP

相关分类

Java
我要回答